1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
#pragma once
#include "Storage.hh"
#include "NTensor.hh"
namespace cadabra {
/// \ingroup numerical
///
/// Functionality to numerically evaluate a scalar expression,
/// give the values of its building blocks.
///
/// The input is a map which relates subtrees in the expression
/// to numerical values. The `evaluate` function will then do a
/// post-order iteration over the tree, collecting and combining
/// the values thus obtained.
///
/// Currently needs the leaf nodes to have an entry in the
/// `subtree_values` map; may be extended later to cover values
/// of non-elementary subtrees.
///
/// If the input variables are 'a' NTensors, then at any stage...
class NEvaluator {
public:
NEvaluator(const Ex&);
/// If we know the value of a subtree explicitly as a number,
/// it is stored in this map. These are computed nodes.
std::map<Ex::iterator, NTensor, Ex::iterator_base_less> subtree_values;
/// If we know the value of a subtree is equal to another subtree
/// (either in the same expression or another one), it is stored
/// in the map below. This then still needs a lookup in the
/// `subtree_values` map.
std::map<Ex::iterator, Ex::iterator, Ex::iterator_base_less> subtree_equalities;
/// The expression will get evaluated for a range of values for
/// each unknown sub-expression (variable). These are set in
/// the map below.
class VariableValues {
public:
Ex variable;
NTensor values;
std::vector<Ex::iterator> locations;
};
std::vector<VariableValues> variable_values;
/// Set the range of values which we want to insert into the
/// indicated variable. Fills the map above.
void set_variable(const Ex&, const NTensor& val);
/// Evaluate the expression, using the variable values set in
/// `set_variable`.
NTensor evaluate();
/// PRIVATE:
void find_variable_locations();
private:
const Ex& ex;
};
};
|