Cast from ceres::Jet<double>’ to type ‘double’ ?

4,680 views
Skip to first unread message

3658...@qq.com

unread,
Dec 29, 2017, 5:23:03 PM12/29/17
to Ceres Solver


My function is below, during compilation, it says: 
invalid static_cast from type ‘const ceres::Jet<double, 3>’ to type ‘float’

Because I'm using external function inside, and I have to convert to type float to keep consistent. Is therer a way to do that? 

template <typename T>
      bool operator()(const T* parameters, T* residuals) const
    {
        Eigen::Matrix<T, 3, 1> pose(parameters[0],parameters[1],parameters[2]);
        Eigen::Vector3f pose1 = pose.cast<float>();
        Eigen::Affine2f transform = occ->getTransformForState(pose1);  // transform: rotation->translation


        Eigen::Vector3f tmp1 = occ->interpMapValueWithDerivatives(  transform * currPoint);

        Eigen::Matrix<T, 3, 1> transformedPointData(tmp1.cast<T>());  /// {M,dM/dx,dM/dy}

        T funVal = T(1) - transformedPointData[0];

        residuals[0] = funVal;

        return true;
    }

Keir Mierle

unread,
Dec 30, 2017, 4:41:48 PM12/30/17
to ceres-...@googlegroups.com
Fundamentally, you cannot convert from Jet to Double without breaking your CostFunction (and your optimization), since that will discard the derivative information. You must use the adapter cost_function_to_functor.h functionality to do this.

Take a look at include/ceres/cost_function_to_functor.h. You will have to provide the derivatives of the wrapped cost function. One approach is to use the NumericDiffCostFunction, then wrap that with a CostFunctionToFunctor.

--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/6f7da7c3-1e09-47b1-a38f-bcb430e58f0a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

3658...@qq.com

unread,
Dec 30, 2017, 5:17:22 PM12/30/17
to Ceres Solver
Thank you. Very clear and helpful!


On Saturday, December 30, 2017 at 4:41:48 PM UTC-5, Keir Mierle wrote:
Fundamentally, you cannot convert from Jet to Double without breaking your CostFunction (and your optimization), since that will discard the derivative information. You must use the adapter cost_function_to_functor.h functionality to do this.

Take a look at include/ceres/cost_function_to_functor.h. You will have to provide the derivatives of the wrapped cost function. One approach is to use the NumericDiffCostFunction, then wrap that with a CostFunctionToFunctor.
On Fri, Dec 29, 2017 at 2:23 PM, <3658...@qq.com> wrote:


My function is below, during compilation, it says: 
invalid static_cast from type ‘const ceres::Jet<double, 3>’ to type ‘float’

Because I'm using external function inside, and I have to convert to type float to keep consistent. Is therer a way to do that? 

template <typename T>
      bool operator()(const T* parameters, T* residuals) const
    {
        Eigen::Matrix<T, 3, 1> pose(parameters[0],parameters[1],parameters[2]);
        Eigen::Vector3f pose1 = pose.cast<float>();
        Eigen::Affine2f transform = occ->getTransformForState(pose1);  // transform: rotation->translation


        Eigen::Vector3f tmp1 = occ->interpMapValueWithDerivatives(  transform * currPoint);

        Eigen::Matrix<T, 3, 1> transformedPointData(tmp1.cast<T>());  /// {M,dM/dx,dM/dy}

        T funVal = T(1) - transformedPointData[0];

        residuals[0] = funVal;

        return true;
    }

--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.

Albert Palomer

unread,
Dec 31, 2017, 6:44:14 AM12/31/17
to ceres-...@googlegroups.com
Isn't another option to use template for everything? All the things in your cost function can be converted to an Eigen::Matrix<T,row,col>. If you do this conversion for each of the class members you use in your cost function, you will not need cost_function_to_functor.h (which makes things slower than autodiff).


Albert Palomer Vila

Sameer Agarwal

unread,
Dec 31, 2017, 7:22:01 AM12/31/17
to ceres-...@googlegroups.com
No that is not going to work. Both because, the conversion from Jets to Double/Floats won't happen, and two it will break the chain rule and computation of derivatives.
Sameer


On Sun, Dec 31, 2017 at 5:14 PM Albert Palomer <alber...@gmail.com> wrote:
Isn't another option to use template for everything? All the things in your cost function can be converted to an Eigen::Matrix<T,row,col>. If you do this conversion for each of the class members you use in your cost function, you will not need cost_function_to_functor.h (which makes things slower than autodiff).


Albert Palomer Vila
2017-12-30 22:41 GMT+01:00 Keir Mierle <mie...@gmail.com>:
Fundamentally, you cannot convert from Jet to Double without breaking your CostFunction (and your optimization), since that will discard the derivative information. You must use the adapter cost_function_to_functor.h functionality to do this.

Take a look at include/ceres/cost_function_to_functor.h. You will have to provide the derivatives of the wrapped cost function. One approach is to use the NumericDiffCostFunction, then wrap that with a CostFunctionToFunctor.
On Fri, Dec 29, 2017 at 2:23 PM, <3658...@qq.com> wrote:


My function is below, during compilation, it says: 
invalid static_cast from type ‘const ceres::Jet<double, 3>’ to type ‘float’

Because I'm using external function inside, and I have to convert to type float to keep consistent. Is therer a way to do that? 

template <typename T>
      bool operator()(const T* parameters, T* residuals) const
    {
        Eigen::Matrix<T, 3, 1> pose(parameters[0],parameters[1],parameters[2]);
        Eigen::Vector3f pose1 = pose.cast<float>();
        Eigen::Affine2f transform = occ->getTransformForState(pose1);  // transform: rotation->translation


        Eigen::Vector3f tmp1 = occ->interpMapValueWithDerivatives(  transform * currPoint);

        Eigen::Matrix<T, 3, 1> transformedPointData(tmp1.cast<T>());  /// {M,dM/dx,dM/dy}

        T funVal = T(1) - transformedPointData[0];

        residuals[0] = funVal;

        return true;
    }

--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/CAD3_OrXvwL5JJvUN8zNA8E4xC%3DXUh%3DFNktWBd%3DUNzLOzLSPAdw%40mail.gmail.com.

Sameer Agarwal

unread,
Dec 31, 2017, 7:22:38 AM12/31/17
to ceres-...@googlegroups.com
I strongly recommend reading 

Sameer

3658...@qq.com

unread,
Dec 31, 2017, 3:36:13 PM12/31/17
to Ceres Solver
Thanks. The functions are related to a series of functions about mapping. So its a little troublesome to change all of them to template functions.


On Sunday, December 31, 2017 at 6:44:14 AM UTC-5, Albert Palomer wrote:
Isn't another option to use template for everything? All the things in your cost function can be converted to an Eigen::Matrix<T,row,col>. If you do this conversion for each of the class members you use in your cost function, you will not need cost_function_to_functor.h (which makes things slower than autodiff).


Albert Palomer Vila

2017-12-30 22:41 GMT+01:00 Keir Mierle <mie...@gmail.com>:
Fundamentally, you cannot convert from Jet to Double without breaking your CostFunction (and your optimization), since that will discard the derivative information. You must use the adapter cost_function_to_functor.h functionality to do this.

Take a look at include/ceres/cost_function_to_functor.h. You will have to provide the derivatives of the wrapped cost function. One approach is to use the NumericDiffCostFunction, then wrap that with a CostFunctionToFunctor.
On Fri, Dec 29, 2017 at 2:23 PM, <3658...@qq.com> wrote:


My function is below, during compilation, it says: 
invalid static_cast from type ‘const ceres::Jet<double, 3>’ to type ‘float’

Because I'm using external function inside, and I have to convert to type float to keep consistent. Is therer a way to do that? 

template <typename T>
      bool operator()(const T* parameters, T* residuals) const
    {
        Eigen::Matrix<T, 3, 1> pose(parameters[0],parameters[1],parameters[2]);
        Eigen::Vector3f pose1 = pose.cast<float>();
        Eigen::Affine2f transform = occ->getTransformForState(pose1);  // transform: rotation->translation


        Eigen::Vector3f tmp1 = occ->interpMapValueWithDerivatives(  transform * currPoint);

        Eigen::Matrix<T, 3, 1> transformedPointData(tmp1.cast<T>());  /// {M,dM/dx,dM/dy}

        T funVal = T(1) - transformedPointData[0];

        residuals[0] = funVal;

        return true;
    }

--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.

3658...@qq.com

unread,
Dec 31, 2017, 3:38:12 PM12/31/17
to Ceres Solver
Thanks for making it clear. I'm not sure if its possible to add this feature in the future because g2o doesnt need to consider such type conversion. But I believe ceres will be promising.

3658...@qq.com

unread,
Dec 31, 2017, 3:41:42 PM12/31/17
to Ceres Solver
Another thing is that those functions need to consider integer type in the mapping. So if the Jet type cannot explicitly consider the difference between double and integer, then the templated version still wont work in my case. I expect that in the future version there could be some way.


On Sunday, December 31, 2017 at 6:44:14 AM UTC-5, Albert Palomer wrote:
Isn't another option to use template for everything? All the things in your cost function can be converted to an Eigen::Matrix<T,row,col>. If you do this conversion for each of the class members you use in your cost function, you will not need cost_function_to_functor.h (which makes things slower than autodiff).


Albert Palomer Vila

2017-12-30 22:41 GMT+01:00 Keir Mierle <mie...@gmail.com>:
Fundamentally, you cannot convert from Jet to Double without breaking your CostFunction (and your optimization), since that will discard the derivative information. You must use the adapter cost_function_to_functor.h functionality to do this.

Take a look at include/ceres/cost_function_to_functor.h. You will have to provide the derivatives of the wrapped cost function. One approach is to use the NumericDiffCostFunction, then wrap that with a CostFunctionToFunctor.
On Fri, Dec 29, 2017 at 2:23 PM, <3658...@qq.com> wrote:


My function is below, during compilation, it says: 
invalid static_cast from type ‘const ceres::Jet<double, 3>’ to type ‘float’

Because I'm using external function inside, and I have to convert to type float to keep consistent. Is therer a way to do that? 

template <typename T>
      bool operator()(const T* parameters, T* residuals) const
    {
        Eigen::Matrix<T, 3, 1> pose(parameters[0],parameters[1],parameters[2]);
        Eigen::Vector3f pose1 = pose.cast<float>();
        Eigen::Affine2f transform = occ->getTransformForState(pose1);  // transform: rotation->translation


        Eigen::Vector3f tmp1 = occ->interpMapValueWithDerivatives(  transform * currPoint);

        Eigen::Matrix<T, 3, 1> transformedPointData(tmp1.cast<T>());  /// {M,dM/dx,dM/dy}

        T funVal = T(1) - transformedPointData[0];

        residuals[0] = funVal;

        return true;
    }

--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.

Keir Mierle

unread,
Jan 1, 2018, 3:00:56 AM1/1/18
to ceres-...@googlegroups.com
On Sun, Dec 31, 2017 at 12:38 PM, <3658...@qq.com> wrote:
Thanks for making it clear. I'm not sure if its possible to add this feature in the future because g2o doesnt need to consider such type conversion. But I believe ceres will be promising.

You can't get around needing the derivatives of your non-Jet code, unless you decide to use a non-Ceres derivative-free solver. Those solvers tend to have much slower convergence than optimizers using derivatives. It's a fundamental optimization issue, unrelated to Ceres on g2o. If you were to do the "conversion" and shed the derivatives, it's likely that your optimization will not work well, and unfortunately will make Ceres look bad when the problem is in your derivatives.

The easiest solution is the one with a numeric diff wrapper, as described here:

To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/3368cdd5-71ed-437b-bf11-f9efd587e3fd%40googlegroups.com.

Keir Mierle

unread,
Jan 1, 2018, 3:06:04 AM1/1/18
to ceres-...@googlegroups.com
I'm not sure what you mean by integer type. Ceres is a continuous optimizer that has no handling for integers; it's a straight least-squares optimizer and not a mixed-integer optimizer. Generally, if you have values that must be integers (and hence have step-function behavior and zero derivatives everywhere and undefined derivatives at integer positions) the behavior will be poor. I expect g2o will be the same, unless there is some special integer handling functionality (can you send a link showing that?)

Based on your cost function, it looks like you could use Ceres' cubic interpolation code which handles taking derivatives automatically; see:
"A function that is defined as a table of values": http://ceres-solver.org/interfacing_with_autodiff.html
and ./include/ceres/cubic_interpolation.h

To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/cead520b-d651-4f18-9cfb-7cc5888d340a%40googlegroups.com.

3658...@qq.com

unread,
Jan 1, 2018, 2:16:14 PM1/1/18
to Ceres Solver
my function "interpMapValueWithDerivatives" will manipulate on grid maps where the grid nodes coordinates are integers.
I dont need to derive around those grids but just transform my laser point coordinate into the grid map and return its coordinate. So in that function, there are some manipulations such as floor() to round the float to integer.
I havent tried if floor() can process jet types and it will be lots of work to make those related function in my program templated version.

Do you have any idea if its feasible? Otherwise, I need to figure out other ways.

William Rucklidge

unread,
Jan 2, 2018, 12:41:00 PM1/2/18
to ceres-...@googlegroups.com
If you're doing grid lookup you can try to use Grid2D and CubicInterpolator. That will let you do the moral equivalent of
T x = ...;
T y = ...;
T v = grid[x][y];
but will do interpolation and chaining so that it also computes the partials of v wrt x and y (and whatever they depend on in turn).

If the values in your grid are not smooth (e.g., a depth map, with real discontinuities in it) the results may not be ideal - but that's unavoidable given that there's a fundamental assumption of continuity in Ceres.

To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/71306284-7c70-40ec-bee9-c5014b4443f6%40googlegroups.com.

3658...@qq.com

unread,
Jan 2, 2018, 1:57:51 PM1/2/18
to Ceres Solver
I will consider that. Thank you!
Reply all
Reply to author
Forward
0 new messages