Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F386816
FunctionAbstractions.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
11 KB
Referenced Files
None
Subscribers
None
FunctionAbstractions.hpp
View Options
//===-- rosa/agent/FunctionAbstractions.hpp ---------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/agent/FunctionAbstractions.hpp
///
/// \author Benedikt Tutzer (benedikt.tutzer@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Definition of *FunctionAbstractions* *functionality*.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_AGENT_FUNCTIONABSTRACTIONS_HPP
#define ROSA_AGENT_FUNCTIONABSTRACTIONS_HPP
#include
"rosa/agent/Abstraction.hpp"
#include
"rosa/agent/Functionality.h"
#include
"rosa/support/debug.hpp"
#include
<algorithm>
#include
<cmath>
#include
<memory>
#include
<vector>
namespace
rosa
{
namespace
agent
{
//@benedikt: check if your partialfunctions can take infinity as
// argument
/// Implements \c rosa::agent::Abstraction as a linear function,
/// y = Coefficient * X + Intercept.
///
/// \note This implementation is supposed to be used to represent a linear
/// function from an arithmetic domain to an arithmetic range. This is enforced
/// statically.
///
/// \tparam D type of the functions domain
/// \tparam R type of the functions range
template
<
typename
D
,
typename
R
>
class
LinearFunction
:
public
Abstraction
<
D
,
R
>
{
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT
((
std
::
is_arithmetic
<
D
>::
value
),
"LinearFunction not arithmetic T"
);
STATIC_ASSERT
((
std
::
is_arithmetic
<
R
>::
value
),
"LinearFunction not to arithmetic"
);
protected
:
/// The Intercept of the linear function
const
D
Intercept
;
/// The Coefficient of the linear function
const
D
Coefficient
;
public
:
/// Creates an instance.
///
/// \param Intercept the intercept of the linear function
/// \param Coefficient the coefficient of the linear function
LinearFunction
(
D
Intercept
,
D
Coefficient
)
noexcept
:
Abstraction
<
D
,
R
>
(
Intercept
),
Intercept
(
Intercept
),
Coefficient
(
Coefficient
)
{}
/// Creates an instance given the two points on a linear function.
///
/// \param x1 The x-value of the first point
/// \param y1 The x-value of the first point
/// \param x2 The y-value of the second point
/// \param y2 The y-value of the second point
LinearFunction
(
D
x1
,
R
y1
,
D
x2
,
R
y2
)
noexcept
:
LinearFunction
<
D
,
R
>
(
y1
-
x1
*
(
y1
-
y2
)
/
(
x1
-
x2
),
(
y1
-
y2
)
/
(
x1
-
x2
))
{}
/// Creates an instance given the two points on a linear function.
///
/// \param p1 The coordinates of the first point
/// \param p2 The coordinates of the second point
LinearFunction
(
std
::
pair
<
D
,
R
>
p1
,
std
::
pair
<
D
,
R
>
p2
)
noexcept
:
LinearFunction
<
D
,
R
>
(
p1
.
first
,
p1
.
second
,
p2
.
first
,
p2
.
second
)
{}
/// Destroys \p this object.
~
LinearFunction
(
void
)
=
default
;
/// Checks wether the Abstraction evaluates to default at the given position
/// As LinearFunctions can be evaluated everythwere, this is always false
///
/// \param V the value at which to check if the function falls back to it's
/// default value.
///
/// \return false
bool
isDefaultAt
(
const
D
&
V
)
const
noexcept
override
{
(
void
)
V
;
return
false
;
}
/// Getter for member variable Intercept
///
/// \return Intercept
D
getIntercept
()
const
{
return
Intercept
;
}
/// Setter for member variable Intercept
///
/// \param Intercept the new Intercept
void
setIntercept
(
const
D
&
Intercept
)
{
this
->
Intercept
=
Intercept
;
}
/// Getter for member variable Coefficient
///
/// \return Coefficient
D
getCoefficient
()
const
{
return
Coefficient
;
}
/// Setter for member variable Coefficient
///
/// \param Coefficient the new Intercept
void
setCoefficient
(
const
D
&
Coefficient
)
{
this
->
Coefficient
=
Coefficient
;
}
/// Set Intercept and Coefficient from two points on the linear function
///
/// \param x1 The x-value of the first point
/// \param y1 The x-value of the first point
/// \param x2 The y-value of the second point
/// \param y2 The y-value of the second point
void
setFromPoints
(
D
x1
,
R
y1
,
D
x2
,
R
y2
)
{
Coefficient
=
(
y1
-
y2
)
/
(
x1
-
x2
);
Intercept
=
y1
-
Coefficient
*
x1
;
}
/// Set Intercept and Coefficient from two points on the linear function
///
/// \param p1 The coordinates of the first point
/// \param p2 The coordinates of the second point
inline
void
setFromPoints
(
std
::
pair
<
D
,
R
>
p1
,
std
::
pair
<
D
,
R
>
p2
)
{
setFromPoints
(
p1
.
first
,
p1
.
second
,
p2
.
first
,
p2
.
second
);
}
/// Evaluates the linear function
///
/// \param X the value at which to evaluate the function
///
/// \return Coefficient*X + Intercept
virtual
R
operator
()(
const
D
&
X
)
const
noexcept
override
{
return
Intercept
+
X
*
Coefficient
;
}
};
/// Implements \c rosa::agent::Abstraction as a sine function,
/// y = Amplitude * sin(Frequency * X + Phase) + Average.
///
/// \note This implementation is supposed to be used to represent a sine
/// function from an arithmetic domain to an arithmetic range. This is enforced
/// statically.
///
/// \tparam D type of the functions domain
/// \tparam R type of the functions range
template
<
typename
D
,
typename
R
>
class
SineFunction
:
public
Abstraction
<
D
,
R
>
{
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT
((
std
::
is_arithmetic
<
D
>::
value
),
"SineFunction not arithmetic T"
);
STATIC_ASSERT
((
std
::
is_arithmetic
<
R
>::
value
),
"SineFunction not to arithmetic"
);
protected
:
/// The frequency of the sine wave
const
D
Frequency
;
/// The Ampiltude of the sine wave
const
D
Amplitude
;
/// The Phase-shift of the sine wave
const
D
Phase
;
/// The y-shift of the sine wave
const
D
Average
;
public
:
/// Creates an instance.
///
/// \param Frequency the frequency of the sine wave
/// \param Amplitude the amplitude of the sine wave
/// \param Phase the phase of the sine wave
/// \param Average the average of the sine wave
SineFunction
(
D
Frequency
,
D
Amplitude
,
D
Phase
,
D
Average
)
noexcept
:
Abstraction
<
D
,
R
>
(
Average
),
Frequency
(
Frequency
),
Amplitude
(
Amplitude
),
Phase
(
Phase
),
Average
(
Average
)
{}
/// Destroys \p this object.
~
SineFunction
(
void
)
=
default
;
/// Checks wether the Abstraction evaluates to default at the given position
/// As SineFunctions can be evaluated everythwere, this is always false
///
/// \param V the value at which to check if the function falls back to it's
/// default value.
///
/// \return false
bool
isDefaultAt
(
const
D
&
V
)
const
noexcept
override
{
(
void
)
V
;
return
false
;
}
/// Evaluates the sine function
///
/// \param X the value at which to evaluate the function
/// \return the value of the sine-function at X
virtual
R
operator
()(
const
D
&
X
)
const
noexcept
override
{
return
Amplitude
*
sin
(
Frequency
*
X
+
Phase
)
+
Average
;
}
};
enum
StepDirection
{
StepUp
,
StepDown
};
/// Implements \c rosa::agent::PartialFunction as a step function from 0 to 1
/// with a ramp in between
///
/// \tparam D type of the functions domain
/// \tparam R type of the functions range
template
<
typename
D
,
typename
R
>
class
StepFunction
:
public
Abstraction
<
D
,
R
>
{
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT
((
std
::
is_arithmetic
<
D
>::
value
),
"abstracting not arithmetic"
);
STATIC_ASSERT
((
std
::
is_arithmetic
<
R
>::
value
),
"abstracting not to arithmetic"
);
private
:
D
Coefficient
;
D
RightLimit
;
StepDirection
Direction
;
public
:
/// Creates an instance by Initializing the underlying \c Abstraction.
///
/// \param Coefficient Coefficient of the ramp
/// \param Direction wether to step up or down
///
/// \pre Coefficient > 0
StepFunction
(
D
Coefficient
,
StepDirection
Direction
=
StepUp
)
:
Abstraction
<
D
,
R
>
(
0
),
Coefficient
(
Coefficient
),
RightLimit
(
1.0f
/
Coefficient
),
Direction
(
Direction
)
{
ASSERT
(
Coefficient
>
0
);
}
/// Destroys \p this object.
~
StepFunction
(
void
)
=
default
;
/// Setter for Coefficient
///
/// \param Coefficient the new Coefficient
void
setCoefficient
(
const
D
&
Coefficient
)
{
ASSERT
(
Coefficient
>
0
);
this
->
Coefficient
=
Coefficient
;
this
->
RightLimit
=
1
/
Coefficient
;
}
/// Setter for RightLimit
///
/// \param _RightLimit the new RightLimit
void
setRightLimit
(
const
D
&
_RightLimit
)
{
ASSERT
(
_RightLimit
>
0
);
this
->
RightLimit
=
_RightLimit
;
this
->
Coefficient
=
1
/
_RightLimit
;
}
/// Checks wether the Abstraction evaluates to default at the given position
///
/// \param V the value at which to check if the function falls back to it's
/// default value.
///
/// \return false if the is negative, true otherwise
bool
isDefaultAt
(
const
D
&
V
)
const
noexcept
override
{
return
V
>
0
;
}
/// Executes the Abstraction
///
/// \param V value to abstract
///
/// \return the abstracted value
R
operator
()(
const
D
&
V
)
const
noexcept
override
{
R
ret
=
0
;
if
(
V
<=
0
)
ret
=
0
;
else
if
(
V
>=
RightLimit
)
ret
=
1
;
else
ret
=
V
*
Coefficient
;
return
Direction
==
StepDirection
::
StepUp
?
ret
:
1
-
ret
;
}
};
/// Implements \c rosa::agent::Abstraction as a partial function from a domain
/// to a range.
///
/// \note This implementation is supposed to be used to represent a partial
/// function from an arithmetic domain to an arithmetic range. This is enforced
/// statically.
///
/// A partial function is defined as a list of abstractions, where each
/// abstraction is associated a range in which it is defined. These ranges must
/// be mutually exclusive.
///
/// \tparam D type of the functions domain
/// \tparam R type of the functions range
template
<
typename
D
,
typename
R
>
class
PartialFunction
:
public
Abstraction
<
D
,
R
>
{
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT
((
std
::
is_arithmetic
<
D
>::
value
),
"abstracting not arithmetic"
);
STATIC_ASSERT
((
std
::
is_arithmetic
<
R
>::
value
),
"abstracting not to arithmetic"
);
private
:
/// A \c rosa::agent::RangeAbstraction RA is used to represent the association
/// from ranges to Abstractions.
/// This returns the Abstraction that is defined for any given value, or
/// a default Abstraction if no Abstraction is defined for that value.
RangeAbstraction
<
D
,
std
::
shared_ptr
<
Abstraction
<
D
,
R
>>>
RA
;
public
:
/// Creates an instance by Initializing the underlying \c Abstraction.
///
/// \param Map the mapping to do abstraction according to
/// \param Default abstraction to abstract to by default
///
/// \pre Each key defines a valid range such that `first <= second` and
/// there are no overlapping ranges defined by the keys.
PartialFunction
(
const
std
::
map
<
std
::
pair
<
D
,
D
>
,
std
::
shared_ptr
<
Abstraction
<
D
,
R
>>>
&
Map
,
const
R
Default
)
:
Abstraction
<
D
,
R
>
(
Default
),
RA
(
Map
,
std
::
shared_ptr
<
Abstraction
<
D
,
R
>>
(
new
Abstraction
<
D
,
R
>
(
Default
)))
{
}
/// Destroys \p this object.
~
PartialFunction
(
void
)
=
default
;
/// Checks wether the Abstraction evaluates to default at the given position
///
/// \param V the value at which to check if the function falls back to it's
/// default value.
///
/// \return false if the value falls into a defined range and the Abstraction
/// defined for that range does not fall back to it's default value.
bool
isDefaultAt
(
const
D
&
V
)
const
noexcept
override
{
return
RA
.
isDefaultAt
(
V
)
?
true
:
RA
(
V
)
->
isDefaultAt
(
V
);
}
/// Searches for an Abstraction for the given value and executes it for that
/// value, if such an Abstraction is found. The default Abstraction is
/// evaluated otherwise.
///
/// \param V value to abstract
///
/// \return the abstracted value based on the set mapping
R
operator
()(
const
D
&
V
)
const
noexcept
override
{
return
RA
(
V
)
->
operator
()(
V
);
}
};
}
// End namespace agent
}
// End namespace rosa
#endif
// ROSA_AGENT_FUNCTIONABSTRACTIONS_HPP
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Fri, Jul 4, 8:26 AM (2 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157556
Default Alt Text
FunctionAbstractions.hpp (11 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment