Mapping Inversion

Mapping objects can (in certain limits) return their own inverse-functions.
See for instance source:trunk/nemomath/examples/ExampleMappingArithmetics.cpp
Custom mappings need to define the getInverse() function for this functionality.

Inversion of operators

A rather special aspect is the inversion of Mappings that are defined by operators such as

RealMapping m = 2.0 * arg<double>();

Mappings like this are invertible:
RealMapping mInv = m.inverse(); // divide by two

For this to be possible, NemoMath defines Inverse elements for datatypes like double.
Therefore the above statement does not actually evaluate to arg<double>() / 2.0. Instead,
NemoMath uses a method leftMultInverse<double>(const double&) to see that left-multiplication
with 2.0 can be reverted by left-multiplication with 0.5. Hence, the concrete inversion evaluates
to 0.5 * arg<double>().

But why shouldn't NemoMath use arg<double>() / 2.0?

The reason for that detour is that not all
types define operators like * and / in pairs:
  • NemoMath's Vector and Matrix clases only provide *, but not /.
  • std::string defines +, but not -.
  • Timestamps like Boost's ptime define -, but not +.

If NemoMath would try to use inverse operators, like inverting + with -, the Mappings
could not be used for such types. It simply wouldn't compile.

However, using inverse elements comes with some functional restrictions, since not all data-types have inverse
elements, although an inverse might be computed with inverse operators:
  • int numbers have no inverse element with respect to multiplication. There is not element I in int such that I*2*x==x.
  • The same holds for unsigned int values with respect to addition.

A further, general restriction is that operator Mappings can only be inverted, if the argument appears only on one side of the operator.
Mappings like

RealMapping f = arg<double>() * someOtherFunction;

are not invertible in a generic way.