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
|
// 2010 © Václav Šmilauer <eudoxos@arcig.cz>
#pragma once
#include <lib/base/AliasNamespaces.hpp>
#include <lib/serialization/Serializable.hpp>
#include <boost/unordered_map.hpp>
namespace yade { // Cannot have #include directive inside.
/* Future optimizations, in postLoad:
1. Use matches to update lookup table/hash for faster matching, instead of traversing matches every time
2. Use algo to update fbPtr, instead of string-comparison of algo every time
*/
class MatchMaker : public Serializable {
Real fbZero(Real /*v1*/, Real /*v2*/) const { return 0.; }
Real fbAvg(Real v1, Real v2) const { return (v1 + v2) / 2.; }
Real fbMin(Real v1, Real v2) const { return math::min(v1, v2); }
Real fbMax(Real v1, Real v2) const { return math::max(v1, v2); }
Real fbHarmAvg(Real v1, Real v2) const { return 2 * v1 * v2 / (v1 + v2); }
Real fbVal(Real /*v1*/, Real /*v2*/) const { return val; }
Real (MatchMaker::*fbPtr)(Real, Real) const;
// whether the current fbPtr function needs valid input values in order to give meaningful result.
// must be kept in sync with fbPtr, which is done in postLoad
bool fbNeedsValues;
// unordered set for a fast coefficient search
boost::unordered_map<std::pair<int, int>, Real> matchSet;
public:
virtual ~MatchMaker() {};
MatchMaker(std::string _algo)
: algo(_algo)
{
postLoad(*this);
}
MatchMaker(Real _val)
: algo("val")
, val(_val)
{
postLoad(*this);
}
Real computeFallback(Real val1, Real val2) const;
void postLoad(MatchMaker&);
// return value looking up matches for id1+id2 (the order is arbitrary)
// if no match is found, use val1,val2 and algo strategy to compute new value.
// if no match is found and val1 or val2 are not given, throw exception
Real operator()(const int id1, const int id2, const Real val1 = NaN, const Real val2 = NaN) const;
// clang-format off
YADE_CLASS_BASE_DOC_ATTRS_CTOR_PY(MatchMaker,Serializable,"Class matching pair of ids to return pre-defined (for a pair of ids defined in :yref:`matches<MatchMaker.matches>`) or derived value (computed using :yref:`algo<MatchMaker.algo>`) of a scalar parameter. It can be called (``id1``, ``id2``, ``val1=NaN``, ``val2=NaN``) in both python and c++. \n\n.. note:: There is a :ref:`converter <customconverters>` from python number defined for this class, which creates a new :yref:`MatchMaker` returning the value of that number; instead of giving the object instance therefore, you can only pass the number value and it will be converted automatically.",
((std::vector<Vector3r>,matches,,Attr::readonly,"Array of ``(id1,id2,value)`` items; queries matching ``id1`` + ``id2`` or ``id2`` + ``id1`` will return ``value``"))
((std::string,algo,"avg",Attr::triggerPostLoad,"Algorithm used to compute value when no match for ids is found within :yref:`matches<MatchMaker.matches>`. Possible values are\n\n* 'avg' (arithmetic average)\n* 'min' (minimum value)\n* 'max' (maximum value)\n* 'harmAvg' (harmonic average)\n\nThe other following algo algorithms do *not* require meaningful input values in order to work:\n\n* 'val' (return value specified by :yref:`val<MatchMaker.val>`)\n* 'zero' (always return 0.)\n\n"))
((Real,val,NaN,,"Constant value returned if there is no match and :yref:`algo<MatchMaker::algo>` is ``val``"))
, fbPtr=&MatchMaker::fbAvg; fbNeedsValues=true; /* keep in sync with the algo value for algo */
, /*py*/ .def("__call__",&MatchMaker::operator(),(py::arg("id1"),py::arg("id2"),py::arg("val1")=NaN,py::arg("val2")=NaN),"Ask the instance for scalar value for given pair *id1*,*id2* (the order is irrelevant). Optionally, *val1*, *val2* can be given so that if there is no :yref:`match<MatchMaker.matches>`, return value can be computed using given :yref:`algo<MatchMaker.algo>`. If there is no match and *val1*, *val2* are not given, an exception is raised.")
.def("computeFallback",&MatchMaker::computeFallback,(py::arg("val1"),py::arg("val2")),"Compute algo value for *val1* and *val2*, using algorithm specified by :yref:`algo<MatchMaker.algo>`.")
);
// clang-format on
};
REGISTER_SERIALIZABLE(MatchMaker);
} // namespace yade
|