24 package org.lightjason.agentspeak.consistency;
26 import cern.colt.function.tdouble.DoubleFunction;
27 import cern.colt.matrix.tdouble.DoubleFactory1D;
28 import cern.colt.matrix.tdouble.DoubleMatrix1D;
29 import cern.colt.matrix.tdouble.DoubleMatrix2D;
30 import cern.colt.matrix.tdouble.algo.DenseDoubleAlgebra;
31 import cern.colt.matrix.tdouble.algo.decomposition.DenseDoubleEigenvalueDecomposition;
32 import cern.colt.matrix.tdouble.impl.DenseDoubleMatrix1D;
33 import cern.colt.matrix.tdouble.impl.DenseDoubleMatrix2D;
34 import cern.jet.math.tdouble.DoubleFunctions;
35 import cern.jet.math.tdouble.DoubleMult;
36 import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
37 import org.apache.commons.math3.stat.descriptive.SynchronizedDescriptiveStatistics;
44 import javax.annotation.Nonnegative;
45 import javax.annotation.Nonnull;
46 import java.text.MessageFormat;
47 import java.util.AbstractMap;
48 import java.util.ArrayList;
50 import java.util.concurrent.ConcurrentHashMap;
51 import java.util.stream.IntStream;
52 import java.util.stream.Stream;
63 private static final Map.Entry<Double, Double>
DEFAULTNONEXISTING =
new AbstractMap.SimpleImmutableEntry<>( 1.0, 0.0 );
67 private static final DenseDoubleAlgebra
ALGEBRA = DenseDoubleAlgebra.DEFAULT;
79 private final Map<IAgent<?>, Map.Entry<Double, Double>>
m_data =
new ConcurrentHashMap<>();
83 private final DescriptiveStatistics
m_statistic =
new SynchronizedDescriptiveStatistics();
112 final int p_iteration,
final double p_epsilon )
116 m_algorithm = p_algorithm;
117 m_iteration = p_iteration;
118 m_epsilon = p_epsilon;
132 m_data.putIfAbsent( p_object, DEFAULTNONEXISTING );
139 if ( m_data.size() < 2 )
143 final ArrayList<IAgent<?>> l_keys =
new ArrayList<>( m_data.keySet() );
146 final DoubleMatrix2D l_matrix =
new DenseDoubleMatrix2D( m_data.size(), m_data.size() );
147 IntStream.range( 0, l_keys.size() )
152 final IAgent<?> l_item = l_keys.get( i );
153 IntStream.range( i + 1, l_keys.size() )
157 final double l_value = this.
getMetricValue( l_item, l_keys.get( j ) );
158 l_matrix.setQuick( i, j, l_value );
159 l_matrix.setQuick( j, i, l_value );
163 final double l_norm = ALGEBRA.norm1( l_matrix.viewRow( i ) );
165 l_matrix.viewRow( i ).assign( DoubleMult.div( l_norm ) );
168 l_matrix.setQuick( i, i, m_epsilon );
172 final DoubleMatrix1D l_eigenvector = l_matrix.zSum() <= m_data.size() * m_epsilon
173 ?
new DenseDoubleMatrix1D( m_data.size() )
177 final DoubleMatrix1D l_invertedeigenvector =
new DenseDoubleMatrix1D( l_eigenvector.toArray() );
178 l_invertedeigenvector.assign( PROBABILITYINVERT );
179 l_invertedeigenvector.assign( DoubleFunctions.div( ALGEBRA.norm1( l_eigenvector ) ) );
183 IntStream.range( 0, l_keys.size() )
187 m_statistic.addValue( l_eigenvector.get( i ) );
188 m_data.put( l_keys.get( i ),
new AbstractMap.SimpleImmutableEntry<>( l_invertedeigenvector.get( i ), l_eigenvector.get( i ) ) );
198 m_data.
remove( p_object );
229 return m_data.entrySet().stream().map( i ->
new AbstractMap.SimpleImmutableEntry<>( i.getKey(), i.getValue().getKey() ) );
236 return m_data.getOrDefault( p_object, DEFAULTNONEXISTING ).getKey();
243 return m_data.getOrDefault( p_object, DEFAULTNONEXISTING ).getValue();
250 return m_data.entrySet().stream().map( i ->
new AbstractMap.SimpleImmutableEntry<>( i.getKey(), i.getValue().getValue() ) );
256 return MessageFormat.format(
"{0}{1}", super.toString(),
m_data );
268 if ( p_first.equals( p_second ) )
271 return m_metric.apply(
272 m_filter.apply( p_first ),
273 m_filter.apply( p_second )
355 final DoubleMatrix1D l_eigenvector;
359 l_eigenvector = getLargestEigenvector( p_matrix, p_iteration );
363 l_eigenvector = getLargestEigenvector( p_matrix );
371 l_eigenvector.assign( DoubleMult.div( ALGEBRA.norm1( l_eigenvector ) ) );
372 l_eigenvector.assign( DoubleFunctions.abs );
374 return l_eigenvector;
388 final DoubleMatrix1D l_probability = DoubleFactory1D.dense.random( p_matrix.rows() );
389 IntStream.range( 0, p_iteration )
392 l_probability.assign( ALGEBRA.mult( p_matrix, l_probability ) );
393 l_probability.assign( DoubleMult.div( ALGEBRA.norm2( l_probability ) ) );
395 return l_probability;
406 final DenseDoubleEigenvalueDecomposition l_eigen =
new DenseDoubleEigenvalueDecomposition( p_matrix );
409 final double[] l_eigenvalues = l_eigen.getRealEigenvalues().toArray();
410 return l_eigen.getV().viewColumn(
411 IntStream.range( 0, l_eigenvalues.length - 1 ).parallel()
412 .reduce( ( i, j ) -> l_eigenvalues[i] < l_eigenvalues[j] ? j : i ).orElse( 0 )
final IFilter m_filter
metric filter
static DoubleMatrix1D getLargestEigenvector(final DoubleMatrix2D p_matrix)
get the largest eigen vector with QR decomposition
static IConsistency heuristic(final IFilter p_filter, final IMetric p_metric, final int p_iteration)
factory heuristic algorithm
final IConsistency call()
final IMetric metric()
returns the used metric
final Stream< Map.Entry< IAgent<?>, Double > > inconsistency()
stream over all data
filtering interface of agent literal values for metric
static final DoubleFunction PROBABILITYINVERT
function for inverting probability
metric interface of the coherency structure
final Stream< Map.Entry< IAgent<?>, Double > > consistency()
stream over all data
final IConsistency add( @Nonnull final IAgent<?> p_object)
adds a new object
final IMetric m_metric
metric object to create the consistency of two objects
layer with consistency data based a markov-chain
final DoubleMatrix1D getStationaryDistribution(final int p_iteration, final DoubleMatrix2D p_matrix)
calculates the stationary distribution
static< T > String languagestring(final T p_source, final String p_label, final Object... p_parameter)
returns the language depend string on any object
final Map< IAgent<?>, Map.Entry< Double, Double > > m_data
map with object and consistency & inconsistency value
numeric algorithm structure
static final DenseDoubleAlgebra ALGEBRA
algebra
static final Map.Entry< Double, Double > DEFAULTNONEXISTING
default value on non-existing objects
CConsistency( @Nonnull final EAlgorithm p_algorithm, @Nonnull final IFilter p_filter, @Nonnull final IMetric p_metric, final int p_iteration, final double p_epsilon)
ctor
double getMetricValue(final IAgent<?> p_first, final IAgent<?> p_second)
returns metric consistency
final double consistency( @Nonnull final IAgent<?> p_object)
returns the consistency of an object
final int m_iteration
number of iterations of the stochastic algorithm
static IConsistency numeric(final IFilter p_filter, final IMetric p_metric)
factory numerical algorithm
final IConsistency clear()
clear
static IConsistency heuristic(final IFilter p_filter, final IMetric p_metric, final int p_iteration, final double p_epsilon)
factory numerical algorithm
IConsistency clear()
clear
final IFilter filter()
returns the used metric filter
final EAlgorithm m_algorithm
algorithm to calculate stationary probability
NUMERICAL
use numeric algorithm (QR decomposition)
static DoubleMatrix1D getLargestEigenvector(final DoubleMatrix2D p_matrix, final int p_iteration)
get the largest eigen vector based on the perron-frobenius theorem
IConsistency remove( @Nonnull final IAgent<?> p_object)
removes an object
final DescriptiveStatistics m_statistic
descriptive statistic
final double m_epsilon
epsilon consistency to create an aperiodic markow-chain
class for any helper calls
final DescriptiveStatistics statistic()
returns statistic data of the consistency values
use stochastic algorithm (fixpoint iteration)
final double inconsistency( @Nonnull final IAgent<?> p_object)
returns the inconsistency of an object
static IConsistency heuristic(final IFilter p_filter, final IMetric p_metric)
factory heuristic algorithm