Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F19839803
CrossReliability.h
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
19 KB
Referenced Files
None
Subscribers
None
CrossReliability.h
View Options
//===-- rosa/delux/CrossReliability.h ---------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/delux/CrossReliability.h
///
/// \author Daniel Schnoell
///
/// \date 2019
///
/// \brief
///
/// \todo there is 1 exception that needs to be handled correctly.
/// \note the default search function is extremely slow maby this could be done
/// via template for storage class and the functions/methods to efficiently find
/// the correct LinearFunction
//===----------------------------------------------------------------------===//
#ifndef ROSA_AGENT_CROSSRELIABILITY_H
#define ROSA_AGENT_CROSSRELIABILITY_H
#include
"rosa/agent/Abstraction.hpp"
#include
"rosa/agent/Functionality.h"
#include
"rosa/core/forward_declarations.h"
// needed for id_t
#include
"rosa/support/log.h"
// needed for error "handling"
#include
"rosa/agent/ReliabilityConfidenceCombinator.h"
// nedded headers
#include
<string>
#include
<type_traits>
//assert
#include
<vector>
// for static methods
#include
<algorithm>
#include
<numeric>
namespace
rosa
{
namespace
agent
{
/// Calculates the Cross Reliability
/// \brief it uses the state represented by a numerical value and calculates the
/// Reliability of a given agent( represented by there id ) in connection to all
/// other given agents
///
/// \note all combination of agents and there coresponding Cross Reliability
/// function have to be specified
template
<
typename
StateType
,
typename
Type
>
class
CrossReliability
:
public
Abstraction
<
StateType
,
Type
>
{
static_assert
(
std
::
is_arithmetic
<
Type
>::
value
,
"CrossReliability: <Type> has to be arithmetic type
\n
"
);
// sanitny check
static_assert
(
std
::
is_arithmetic
<
StateType
>::
value
,
"CrossReliability: <StateType> has to be arithmetic type
\n
"
);
// sanitny
// check
using
Abstraction
=
typename
rosa
::
agent
::
Abstraction
<
StateType
,
Type
>
;
struct
Functionblock
{
bool
exists
=
false
;
id_t
A
;
id_t
B
;
Abstraction
*
Funct
;
};
/// From Maxi in his code defined as 1 can be changed by set
Type
crossReliabilityParameter
=
1
;
/// Stored Cross Reliability Functions
std
::
vector
<
Functionblock
>
Functions
;
/// Method which is used to combine the generated values
Type
(
*
Method
)(
std
::
vector
<
Type
>
values
)
=
AVERAGE
;
//--------------------------------------------------------------------------------
// helper function
/// evalues the absolute distance between two values
/// \note this is actually the absolute distance but to ceep it somewhat
/// conform with maxis code
template
<
typename
Type_t
>
Type_t
AbsuluteValue
(
Type_t
A
,
Type_t
B
)
{
return
((
A
-
B
)
<
0
)
?
B
-
A
:
A
-
B
;
}
/// verry inefficient searchFunction
Functionblock
(
*
searchFunction
)(
std
::
vector
<
Functionblock
>
vect
,
const
id_t
nameA
,
const
id_t
nameB
)
=
[](
std
::
vector
<
Functionblock
>
vect
,
const
id_t
nameA
,
const
id_t
nameB
)
->
Functionblock
{
for
(
Functionblock
tmp
:
vect
)
{
if
(
tmp
.
A
==
nameA
&&
tmp
.
B
==
nameB
)
return
tmp
;
if
(
tmp
.
A
==
nameB
&&
tmp
.
B
==
nameA
)
return
tmp
;
}
return
Functionblock
();
};
/// evaluest the corisponding LinearFunction thith the score difference
/// \param nameA these two parameters are the unique identifiers for the
/// LinerFunction \param nameB these two parameters are the unique identifiers
/// for the LinerFunction
///
/// \note If the block nameA nameB doesn't exist it logs the error and returns
/// 0
/// \note it doesn't matter if they are swapped
Type
getCrossReliabilityFromProfile
(
id_t
nameA
,
id_t
nameB
,
StateType
scoreDifference
)
{
Functionblock
block
=
searchFunction
(
Functions
,
nameA
,
nameB
);
if
(
!
block
.
exists
)
{
LOG_ERROR
((
"CrossReliability: Block:"
+
std
::
to_string
(
nameA
)
+
","
+
std
::
to_string
(
nameB
)
+
"doesn't exist returning 0"
));
return
0
;
}
return
block
.
Funct
->
operator
()(
scoreDifference
);
}
public
:
/// adds a Cross Reliability Profile used to get the Reliability of the state
/// difference
/// \param idA The id of the one \c Agent ( idealy the id of \c Unit to make
/// it absolutly unique )
///
/// \param idB The id of the other \c Agent
///
/// \param Function A unique pointer to an \c Abstraction it would use the
/// difference in score for its input
void
addCrossReliabilityProfile
(
id_t
idA
,
id_t
idB
,
std
::
unique_ptr
<
Abstraction
>
&
Function
)
{
Abstraction
*
ptr
=
Function
.
release
();
Functions
.
push_back
({
true
,
idA
,
idB
,
ptr
});
}
/// sets the cross reliability parameter
void
setCrossReliabilityParameter
(
Type
val
)
{
crossReliabilityParameter
=
val
;
}
/// sets the used method to combine the values
/// \param Meth The Function which defines the combination method.
/// \note Inside \c CrossReliability there are static methods defined which
/// can be used.
void
setCrossReliabilityMethod
(
Type
(
*
Meth
)(
std
::
vector
<
Type
>
values
))
{
Method
=
Meth
;
}
CrossReliability
()
:
Abstraction
(
0
)
{}
~
CrossReliability
()
{
for
(
auto
tmp
:
Functions
)
delete
tmp
.
Funct
;
Functions
.
clear
();
}
/// Calculets the CrossReliability
/// \note both Main and Slaveagents are represented by there data and an
/// unique identifier
///
/// \param MainAgent defines the value pair around which the Cross Reliability
/// is calculated
/// \param SlaveAgents defines all value pairs of the connected Agents it
/// doesn't matter if Main agent exists inside this vector
Type
operator
()(
std
::
pair
<
id_t
,
StateType
>
&&
MainAgent
,
std
::
vector
<
std
::
pair
<
id_t
,
StateType
>>
&
SlaveAgents
);
/// predefined combination method
static
Type
CONJUNCTION
(
std
::
vector
<
Type
>
values
)
{
return
*
std
::
min_element
(
values
.
begin
(),
values
.
end
());
}
/// predefined combination method
static
Type
AVERAGE
(
std
::
vector
<
Type
>
values
)
{
return
std
::
accumulate
(
values
.
begin
(),
values
.
end
(),
0.0
)
/
values
.
size
();
}
/// predefined combination method
static
Type
DISJUNCTION
(
std
::
vector
<
Type
>
values
)
{
return
*
std
::
max_element
(
values
.
begin
(),
values
.
end
());
}
};
template
<
typename
StateType
,
typename
Type
>
inline
Type
CrossReliability
<
StateType
,
Type
>::
operator
()(
std
::
pair
<
id_t
,
StateType
>
&&
MainAgent
,
std
::
vector
<
std
::
pair
<
id_t
,
StateType
>>
&
SlaveAgents
)
{
Type
crossReliabiability
;
std
::
vector
<
Type
>
values
;
for
(
std
::
pair
<
id_t
,
StateType
>
SlaveAgent
:
SlaveAgents
)
{
if
(
SlaveAgent
.
first
==
MainAgent
.
first
)
continue
;
if
(
MainAgent
.
second
==
SlaveAgent
.
second
)
crossReliabiability
=
1
;
else
crossReliabiability
=
1
/
(
crossReliabilityParameter
*
AbsuluteValue
(
MainAgent
.
second
,
SlaveAgent
.
second
));
// profile reliability
Type
crossReliabilityFromProfile
=
getCrossReliabilityFromProfile
(
MainAgent
.
first
,
SlaveAgent
.
first
,
AbsuluteValue
(
MainAgent
.
second
,
SlaveAgent
.
second
));
values
.
push_back
(
std
::
max
(
crossReliabiability
,
crossReliabilityFromProfile
));
}
return
Method
(
values
);
}
/// Calculates the \c CrossConfidence
/// \brief It uses the a theoretical state represented by a numerical value and
/// calculates the Reliability of a given agent[ represented by there id ] in
/// connection to all other given agents this can be used to get a Confidence of
/// the current state
///
/// \note all combination of agents and there coresponding \c CrossReliability
/// function have to be specified
template
<
typename
StateType
,
typename
Type
>
class
CrossConfidence
:
public
Abstraction
<
StateType
,
Type
>
{
static_assert
(
std
::
is_arithmetic
<
Type
>::
value
,
"CrossConfidence: <Type> has to be an arithmetic type
\n
"
);
static_assert
(
std
::
is_arithmetic
<
StateType
>::
value
,
"CrossConfidence: <StateType> has to be an arithmetic type
\n
"
);
using
Abstraction
=
typename
rosa
::
agent
::
Abstraction
<
StateType
,
Type
>
;
struct
Functionblock
{
bool
exists
=
false
;
id_t
A
;
id_t
B
;
Abstraction
*
Funct
;
};
/// From Maxi in his code defined as 1 can be changed by set
Type
crossReliabilityParameter
=
1
;
/// Stored Cross Reliability Functions
std
::
vector
<
Functionblock
>
Functions
;
/// Method which is used to combine the generated values
Type
(
*
Method
)(
std
::
vector
<
Type
>
values
)
=
AVERAGE
;
//--------------------------------------------------------------------------------
// helper function
/// evalues the absolute distance between two values
/// \note this is actually the absolute distance but to ceep it somewhat
/// conform with maxis code
template
<
typename
Type_t
>
Type_t
AbsuluteValue
(
Type_t
A
,
Type_t
B
)
{
return
((
A
-
B
)
<
0
)
?
B
-
A
:
A
-
B
;
}
/// verry inefficient searchFunction
Functionblock
(
*
searchFunction
)(
std
::
vector
<
Functionblock
>
vect
,
const
id_t
nameA
,
const
id_t
nameB
)
=
[](
std
::
vector
<
Functionblock
>
vect
,
const
id_t
nameA
,
const
id_t
nameB
)
->
Functionblock
{
for
(
Functionblock
tmp
:
vect
)
{
if
(
tmp
.
A
==
nameA
&&
tmp
.
B
==
nameB
)
return
tmp
;
if
(
tmp
.
A
==
nameB
&&
tmp
.
B
==
nameA
)
return
tmp
;
}
return
Functionblock
();
};
/// evaluest the corisponding LinearFunction thith the score difference
/// \param nameA these two parameters are the unique identifiers
/// \param nameB these two parameters are the unique identifiers
/// for the LinerFunction
///
/// \note it doesn't matter if they are swapped
Type
getCrossReliabilityFromProfile
(
id_t
nameA
,
id_t
nameB
,
StateType
scoreDifference
)
{
Functionblock
block
=
searchFunction
(
Functions
,
nameA
,
nameB
);
if
(
!
block
.
exists
)
{
LOG_ERROR
((
"CrossReliability: Block:"
+
std
::
to_string
(
nameA
)
+
","
+
std
::
to_string
(
nameB
)
+
"doesn't exist returning 0"
));
return
0
;
}
return
block
.
Funct
->
operator
()(
scoreDifference
);
}
public
:
/// adds a Cross Reliability Profile used to get the Reliability of the state
/// difference
/// \param idA The id of the one \c Agent ( idealy the id of \c Unit to make
/// it absolutly unique )
///
/// \param idB The id of the other \c Agent
///
/// \param Function A unique pointer to an \c Abstraction it would use the
/// difference in score for its input
void
addCrossReliabilityProfile
(
id_t
idA
,
id_t
idB
,
std
::
unique_ptr
<
Abstraction
>
&
Function
)
{
Abstraction
*
ptr
=
Function
.
release
();
Functions
.
push_back
({
true
,
idA
,
idB
,
ptr
});
}
/// sets the cross reliability parameter
void
setCrossReliabilityParameter
(
Type
val
)
{
crossReliabilityParameter
=
val
;
}
/// sets the used method to combine the values
/// \param Meth The Function which defines the combination method.
/// \note Inside \c CrossReliability there are static methods defined which
/// can be used.
void
setCrossReliabilityMethod
(
Type
(
*
Meth
)(
std
::
vector
<
Type
>
values
))
{
Method
=
Meth
;
}
CrossConfidence
()
:
Abstraction
(
0
)
{}
~
CrossConfidence
()
{
for
(
auto
tmp
:
Functions
)
delete
tmp
.
Funct
;
Functions
.
clear
();
}
Type
operator
()(
id_t
MainAgent
,
StateType
TheoreticalValue
,
std
::
vector
<
std
::
pair
<
id_t
,
StateType
>>
&
SlaveAgents
);
/// predefined combination method
static
Type
CONJUNCTION
(
std
::
vector
<
Type
>
values
)
{
return
*
std
::
min_element
(
values
.
begin
(),
values
.
end
());
}
/// predefined combination method
static
Type
AVERAGE
(
std
::
vector
<
Type
>
values
)
{
return
std
::
accumulate
(
values
.
begin
(),
values
.
end
(),
0.0
)
/
values
.
size
();
}
/// predefined combination method
static
Type
DISJUNCTION
(
std
::
vector
<
Type
>
values
)
{
return
*
std
::
max_element
(
values
.
begin
(),
values
.
end
());
}
};
/// Calculats the CrossConfidence of the main agent compared to all other Agents
/// \param MainAgent The id of the Main agent
/// \param TheoreticalValue The throretical value it should use for calculation
/// \param SlaveAgents The numerical Representation of all other Slave Agents
template
<
typename
StateType
,
typename
Type
>
inline
Type
CrossConfidence
<
StateType
,
Type
>::
operator
()(
id_t
MainAgent
,
StateType
TheoreticalValue
,
std
::
vector
<
std
::
pair
<
id_t
,
StateType
>>
&
SlaveAgents
)
{
Type
crossReliabiability
;
std
::
vector
<
Type
>
values
;
for
(
std
::
pair
<
id_t
,
StateType
>
SlaveAgent
:
SlaveAgents
)
{
if
(
SlaveAgent
.
first
==
MainAgent
)
continue
;
if
(
TheoreticalValue
==
SlaveAgent
.
second
)
crossReliabiability
=
1
;
else
crossReliabiability
=
1
/
(
crossReliabilityParameter
*
AbsuluteValue
(
TheoreticalValue
,
SlaveAgent
.
second
));
// profile reliability
Type
crossReliabilityFromProfile
=
getCrossReliabilityFromProfile
(
MainAgent
,
SlaveAgent
.
first
,
AbsuluteValue
(
TheoreticalValue
,
SlaveAgent
.
second
));
values
.
push_back
(
std
::
max
(
crossReliabiability
,
crossReliabilityFromProfile
));
}
return
Method
(
values
);
}
/// This is the Reliability Functionality for the highlevel Agent.
/// \brief It takes the scores and reliabilities of all connected lowlevel
/// Agents and calculates the Reliability of them together. Also it creates the
/// feedback that is needed by the \c ReliabilityForLowLevelAgents, which is a
/// kind of confidence.
///
/// \tparam StateType Datatype of the State ( Typically double or float)
/// \tparam ReliabilityType Datatype of the Reliability (
/// Typically long or int)
///
/// \note A highlevel Agent is commonly in a master slave relationship with the
/// lowlevel Agents as the master. It combines the Reliability of all connected
/// Slaves and uses that as its own Reliability.
///
/// \note more information about how the Reliability and feedback is
/// created at \c operator()()
// State Type rename
// merge cross rel/conf darein
template
<
typename
StateType
,
typename
ReliabilityType
>
class
CrossCombinator
{
public
:
static_assert
(
std
::
is_arithmetic
<
StateType
>::
value
,
"HighLevel: StateType has to be an arithmetic type
\n
"
);
static_assert
(
std
::
is_arithmetic
<
ReliabilityType
>::
value
,
"HighLevel: ReliabilityType has to be an arithmetic type
\n
"
);
/// typedef To shorten the writing.
/// \c ConfOrRel
typedef
ConfOrRel
<
StateType
,
ReliabilityType
>
ConfOrRel
;
/// typedef of the input type for the operator() defined explicitly to
/// simplify interaction
///
typedef
std
::
vector
<
std
::
tuple
<
id_t
,
StateType
,
ReliabilityType
>>
InputType
;
/// The return type for the \c operator()() Method
struct
returnType
{
ReliabilityType
CrossReliability
;
std
::
map
<
id_t
,
std
::
vector
<
ConfOrRel
>>
CrossConfidence
;
};
/// Calculates the Reliability and the Cross Confidences for each lowlevel
/// Agent for all of there states.
///
/// \param Values It gets the States and Reliabilities of
/// all connected Slaves inside a vector.
///
/// \return it returns a struct \c returnType containing the CrossReliability
/// and all CrossConfidence's
///
/// \brief To calculate the Reliability it combines [\c std::min() ] the \c
/// CrossReliability of all connected Agents. To calculate the feedback it
/// iterates over all Agents and their states and uses the \c CrossConfidence
/// Function to play what if with the states.
returnType
operator
()(
std
::
vector
<
std
::
tuple
<
id_t
,
StateType
,
ReliabilityType
>>
&
Values
)
{
ReliabilityType
combinedInputRel
=
1
;
ReliabilityType
combinedCrossRel
=
1
;
ReliabilityType
outputReliability
;
std
::
vector
<
std
::
pair
<
id_t
,
StateType
>>
Agents
;
std
::
map
<
id_t
,
std
::
vector
<
ConfOrRel
>>
output
;
std
::
vector
<
ConfOrRel
>
output_temporary
;
for
(
auto
tmp
:
Values
)
{
std
::
pair
<
id_t
,
StateType
>
tmp2
;
tmp2
.
first
=
std
::
get
<
0
>
(
tmp
);
tmp2
.
second
=
std
::
get
<
1
>
(
tmp
);
Agents
.
push_back
(
tmp2
);
}
for
(
auto
Value
:
Values
)
{
id_t
id
=
std
::
get
<
0
>
(
Value
);
StateType
sc
=
std
::
get
<
1
>
(
Value
);
ReliabilityType
rel
=
std
::
get
<
2
>
(
Value
);
// combination method ([])
// get input reliability
combinedInputRel
=
std
::
min
(
combinedInputRel
,
rel
);
// calculate the cross reliability for this slave agent
ReliabilityType
realCrossReliabilityOfSlaveAgent
=
CrossReliability
->
operator
()(
{
id
,
sc
},
Agents
);
// AVERAGE, MULTIPLICATION, CONJUNCTION (best to worst:
// AVERAGE = CONJUNCTION > MULTIPLICATION >> )
// get cross confidence
output_temporary
.
clear
();
for
(
StateType
thoScore
:
States
[
id
])
{
// calculate the cross reliability for this slave agent
ConfOrRel
data
;
data
.
score
=
thoScore
;
data
.
Reliability
=
CrossConfidence
->
operator
()(
id
,
thoScore
,
Agents
);
output_temporary
.
push_back
(
data
);
}
output
.
insert
({
id
,
output_temporary
});
// set combination method
// get combined cross reliability
combinedCrossRel
=
std
::
min
(
combinedCrossRel
,
realCrossReliabilityOfSlaveAgent
);
}
// combine cross reliabilites and input reliabilites of all slave agents
// NOTE: options would be multiply, average, AND (best to worst: )
// outputReliability = combinedInputRel * combinedCrossRel;
// outputReliability = (combinedInputRel + combinedCrossRel) / 2;
// set combination method
// get output reliability
outputReliability
=
std
::
min
(
combinedInputRel
,
combinedCrossRel
);
return
{
outputReliability
,
output
};
}
/// This is the setter for CrossReliability Function
/// \param CrossReliability A pointer to the Functional for the
/// CrossReliability
/// \brief This is needed to calculate the Reliability. It uses this on all
/// values of all lowlevel Agnets.
void
setCrossReliability
(
std
::
unique_ptr
<
CrossReliability
<
StateType
,
ReliabilityType
>>
&
CrossReliability
)
{
this
->
CrossReliability
=
std
::
move
(
CrossReliability
);
}
/// This is the setter for CrossConfidence Function
/// \param CrossConfidence A pointer to the Functional for the \c
/// CrossConfidence \brief This is needed for the feedback for the \c
/// ReliabilityForLowLevelAgents.
void
setCrossConfidence
(
std
::
unique_ptr
<
CrossConfidence
<
StateType
,
ReliabilityType
>>
&
CrossConfidence
)
{
this
->
CrossConfidence
=
std
::
move
(
CrossConfidence
);
}
/// This is the adder for the states
/// \param id The id of the Agent of the states
/// \param States id specific states. this will be copied So that if Slaves
/// have different States they can be used correctly.
/// \brief The States of all connected lowlevel Agents has to be known to be
/// able to iterate over them
void
addStates
(
id_t
id
,
std
::
vector
<
StateType
>
States
)
{
this
->
States
.
insert
({
id
,
States
});
}
private
:
std
::
unique_ptr
<
CrossReliability
<
StateType
,
ReliabilityType
>>
CrossReliability
;
std
::
unique_ptr
<
CrossConfidence
<
StateType
,
ReliabilityType
>>
CrossConfidence
;
std
::
map
<
id_t
,
std
::
vector
<
StateType
>>
States
;
};
}
// End namespace agent
}
// End namespace rosa
#endif
// ROSA_AGENT_CROSSRELIABILITY_H
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sun, Jul 12, 6:55 PM (8 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
349673
Default Alt Text
CrossReliability.h (19 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment