| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 | 
							- // Ceres Solver - A fast non-linear least squares minimizer
 
- // Copyright 2019 Google Inc. All rights reserved.
 
- // http://code.google.com/p/ceres-solver/
 
- //
 
- // Redistribution and use in source and binary forms, with or without
 
- // modification, are permitted provided that the following conditions are met:
 
- //
 
- // * Redistributions of source code must retain the above copyright notice,
 
- //   this list of conditions and the following disclaimer.
 
- // * Redistributions in binary form must reproduce the above copyright notice,
 
- //   this list of conditions and the following disclaimer in the documentation
 
- //   and/or other materials provided with the distribution.
 
- // * Neither the name of Google Inc. nor the names of its contributors may be
 
- //   used to endorse or promote products derived from this software without
 
- //   specific prior written permission.
 
- //
 
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
- // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
- // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
- // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
- // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
- // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
- // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
- // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
- // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
- // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
- // POSSIBILITY OF SUCH DAMAGE.
 
- //
 
- // Author: darius.rueckert@fau.de (Darius Rueckert)
 
- //
 
- // TODO: Documentation
 
- #ifndef CERES_PUBLIC_EXPRESSION_REF_H_
 
- #define CERES_PUBLIC_EXPRESSION_REF_H_
 
- #include <string>
 
- #include "ceres/codegen/internal/expression.h"
 
- #include "ceres/codegen/internal/types.h"
 
- namespace ceres {
 
- namespace internal {
 
- // This class represents a scalar value that creates new expressions during
 
- // evaluation. ExpressionRef can be used as template parameter for cost functors
 
- // and Jets.
 
- //
 
- // ExpressionRef should be passed by value.
 
- struct ExpressionRef {
 
-   ExpressionRef() = default;
 
-   // Create a compile time constant expression directly from a double value.
 
-   // This is important so that we can write T(3.14) in our code and
 
-   // it's automatically converted to the correct expression.
 
-   //
 
-   // This constructor is implicit, because the line
 
-   //    T a(0);
 
-   // must work for T = Jet<ExpressionRef>.
 
-   ExpressionRef(double compile_time_constant);
 
-   // By adding this deleted constructor we can detect invalid usage of
 
-   // ExpressionRef. ExpressionRef must only be created from constexpr doubles.
 
-   //
 
-   // If you get a compile error here, you have probably written something like:
 
-   //   T x = local_variable_;
 
-   // Change this into:
 
-   //   T x = CERES_LOCAL_VARIABLE(local_variable_);
 
-   ExpressionRef(double&) = delete;
 
-   // Copy construction/assignment creates an ASSIGNMENT expression from
 
-   // 'other' to 'this'.
 
-   //
 
-   // For example:
 
-   //   a = b;        // With a.id = 5 and b.id = 3
 
-   // will generate the following assignment:
 
-   //   v_5 = v_3;
 
-   //
 
-   //  If 'this' ExpressionRef is currently not pointing to a variable
 
-   // (id==invalid), then an assignment to a new variable is generated. Example:
 
-   //    T a = 5;
 
-   //    T b;
 
-   //    b = a;  // During the assignment 'b' is invalid
 
-   //
 
-   // The right hand side of the assignment (= the argument 'other') must be
 
-   // valid in every case. The following code will result in an error.
 
-   //   T a;
 
-   //   T b = a;  // Error: Uninitialized assignment
 
-   ExpressionRef(const ExpressionRef& other);
 
-   ExpressionRef& operator=(const ExpressionRef& other);
 
-   // Similar to the copy assignment above, but if 'this' is uninitialized, we
 
-   // can remove the copy and therefore eliminate one expression in the graph.
 
-   // For example:
 
-   //   T c;
 
-   //   c = a + b;
 
-   // will generate
 
-   //   v_2 = v_0 + v_1
 
-   // instead of an additional assigment from the temporary 'a + b' to 'c'. In
 
-   // C++ this concept is called "Copy Elision". This is used by the compiler to
 
-   // eliminate copies, for example, in a function that returns an object by
 
-   // value. We implement it ourself here, because large parts of copy elision
 
-   // are implementation defined, which means that every compiler can do it
 
-   // differently. More information on copy elision can be found here:
 
-   // https://en.cppreference.com/w/cpp/language/copy_elision
 
-   ExpressionRef(ExpressionRef&& other);
 
-   ExpressionRef& operator=(ExpressionRef&& other);
 
-   // Compound operators
 
-   ExpressionRef& operator+=(const ExpressionRef& x);
 
-   ExpressionRef& operator-=(const ExpressionRef& x);
 
-   ExpressionRef& operator*=(const ExpressionRef& x);
 
-   ExpressionRef& operator/=(const ExpressionRef& x);
 
-   bool IsInitialized() const { return id != kInvalidExpressionId; }
 
-   // The index into the ExpressionGraph data array.
 
-   ExpressionId id = kInvalidExpressionId;
 
-   static ExpressionRef Create(ExpressionId id);
 
- };
 
- // A helper function which calls 'InsertBack' on the currently active graph.
 
- // This wrapper also checks if StartRecordingExpressions was called. See
 
- // ExpressionGraph::InsertBack for more information.
 
- ExpressionRef AddExpressionToGraph(const Expression& expression);
 
- // Arithmetic Operators
 
- ExpressionRef operator-(const ExpressionRef& x);
 
- ExpressionRef operator+(const ExpressionRef& x);
 
- ExpressionRef operator+(const ExpressionRef& x, const ExpressionRef& y);
 
- ExpressionRef operator-(const ExpressionRef& x, const ExpressionRef& y);
 
- ExpressionRef operator*(const ExpressionRef& x, const ExpressionRef& y);
 
- ExpressionRef operator/(const ExpressionRef& x, const ExpressionRef& y);
 
- // Functions
 
- #define CERES_DEFINE_UNARY_FUNCTION_CALL(name)          \
 
-   inline ExpressionRef name(const ExpressionRef& x) {   \
 
-     return AddExpressionToGraph(                        \
 
-         Expression::CreateFunctionCall(#name, {x.id})); \
 
-   }
 
- #define CERES_DEFINE_BINARY_FUNCTION_CALL(name)                               \
 
-   inline ExpressionRef name(const ExpressionRef& x, const ExpressionRef& y) { \
 
-     return AddExpressionToGraph(                                              \
 
-         Expression::CreateFunctionCall(#name, {x.id, y.id}));                 \
 
-   }
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(abs);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(acos);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(asin);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(atan);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(cbrt);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(ceil);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(cos);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(cosh);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(exp);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(exp2);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(floor);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(log);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(log2);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(sin);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(sinh);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(sqrt);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(tan);
 
- CERES_DEFINE_UNARY_FUNCTION_CALL(tanh);
 
- CERES_DEFINE_BINARY_FUNCTION_CALL(atan2);
 
- CERES_DEFINE_BINARY_FUNCTION_CALL(pow);
 
- #undef CERES_DEFINE_UNARY_FUNCTION_CALL
 
- #undef CERES_DEFINE_BINARY_FUNCTION_CALL
 
- // This additonal type is required, so that we can detect invalid conditions
 
- // during compile time. For example, the following should create a compile time
 
- // error:
 
- //
 
- //   ExpressionRef a(5);
 
- //   CERES_IF(a){           // Error: Invalid conversion
 
- //   ...
 
- //
 
- // Following will work:
 
- //
 
- //   ExpressionRef a(5), b(7);
 
- //   ComparisonExpressionRef c = a < b;
 
- //   CERES_IF(c){
 
- //   ...
 
- struct ComparisonExpressionRef {
 
-   ExpressionId id;
 
-   explicit ComparisonExpressionRef(const ExpressionRef& ref) : id(ref.id) {}
 
- };
 
- ExpressionRef Ternary(const ComparisonExpressionRef& c,
 
-                       const ExpressionRef& x,
 
-                       const ExpressionRef& y);
 
- // Comparison operators
 
- ComparisonExpressionRef operator<(const ExpressionRef& x,
 
-                                   const ExpressionRef& y);
 
- ComparisonExpressionRef operator<=(const ExpressionRef& x,
 
-                                    const ExpressionRef& y);
 
- ComparisonExpressionRef operator>(const ExpressionRef& x,
 
-                                   const ExpressionRef& y);
 
- ComparisonExpressionRef operator>=(const ExpressionRef& x,
 
-                                    const ExpressionRef& y);
 
- ComparisonExpressionRef operator==(const ExpressionRef& x,
 
-                                    const ExpressionRef& y);
 
- ComparisonExpressionRef operator!=(const ExpressionRef& x,
 
-                                    const ExpressionRef& y);
 
- // Logical Operators
 
- ComparisonExpressionRef operator&&(const ComparisonExpressionRef& x,
 
-                                    const ComparisonExpressionRef& y);
 
- ComparisonExpressionRef operator||(const ComparisonExpressionRef& x,
 
-                                    const ComparisonExpressionRef& y);
 
- ComparisonExpressionRef operator!(const ComparisonExpressionRef& x);
 
- template <>
 
- struct InputAssignment<ExpressionRef> {
 
-   using ReturnType = ExpressionRef;
 
-   static inline ReturnType Get(double /* unused */, const char* name) {
 
-     // Note: The scalar value of v will be thrown away, because we don't need it
 
-     // during code generation.
 
-     return AddExpressionToGraph(Expression::CreateInputAssignment(name));
 
-   }
 
- };
 
- template <typename T>
 
- inline typename InputAssignment<T>::ReturnType MakeInputAssignment(
 
-     double v, const char* name) {
 
-   return InputAssignment<T>::Get(v, name);
 
- }
 
- inline ExpressionRef MakeParameter(const std::string& name) {
 
-   return AddExpressionToGraph(Expression::CreateInputAssignment(name));
 
- }
 
- inline ExpressionRef MakeOutput(const ExpressionRef& v,
 
-                                 const std::string& name) {
 
-   return AddExpressionToGraph(Expression::CreateOutputAssignment(v.id, name));
 
- }
 
- }  // namespace internal
 
- template <>
 
- struct ComparisonReturnType<internal::ExpressionRef> {
 
-   using type = internal::ComparisonExpressionRef;
 
- };
 
- }  // namespace ceres
 
- #endif
 
 
  |