Variable residual size

958 views
Skip to first unread message

Albert Palomer

unread,
Sep 19, 2016, 11:33:47 AM9/19/16
to Ceres Solver
Hello,

I have the following problem: I am trying to solve a non-linear least squares problem (problem 1) where the size of the residual block is not known at the compiling time.
My cost function (the one used to solve problem 1) works on 3D points but, to be able to get the error, I need to solve a non-linear least squares problem (problem 2) within the operand() function. For some of the 3D points this non-linear least squares problem is the same. This means that I can either 1) add a residual block for each point and then solve problem 2 one time for each 3D point (although for some I already have it solved), or 2) make residuals bigger by grouping all the points that will use the same problem 2 and compute a residual for all the points with the same problem 2 at once.
I can do as in 1) and add a residual block for each 3D point, however, solving problem 2 is time-consuming. When I try to do it as in 2), I want to do something like:

ceres::CostFunction* cost_function = new ceres::NumericDiffCostFunction<func,ceres::CENTRAL, n_pts, 4>(new func(point));

Obviously func and point are propperly defined and their type match, n_pts is an integer. However, when I compile I get the following error:

the value of 'n_pts' is not usable in a constant expression ceres::CostFunction* cost_function = new ceres::NumericDiffCostFunction<func,ceres::CENTRAL, n_pts, 4>

note: 'n_pts' was not initialized with a constant expression int n_pts(10);


Any idea on how can I make the cos_function variable in size on runtime?


Thank you.


Cheers!

Aditya Gupta

unread,
Sep 19, 2016, 12:00:20 PM9/19/16
to Ceres Solver
I am working with a similar problem of variable size of residual block and this example helped me a lot:

https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/robot_pose_mle.cc

Regards,
Adit

Sameer Agarwal

unread,
Sep 19, 2016, 12:30:35 PM9/19/16
to ceres-...@googlegroups.com
Albert, 

If I understand your problem, you have a two stage optimization, where the residual of one stage depends on the optimal value of the second optimization problem.


On Mon, Sep 19, 2016 at 8:33 AM Albert Palomer <alber...@gmail.com> wrote:
Hello,

I have the following problem: I am trying to solve a non-linear least squares problem (problem 1) where the size of the residual block is not known at the compiling time.
My cost function (the one used to solve problem 1) works on 3D points but, to be able to get the error, I need to solve a non-linear least squares problem (problem 2) within the operand() function.

So far so good.

 
For some of the 3D points this non-linear least squares problem is the same.
 
This means that I can either 1) add a residual block for each point and then solve problem 2 one time for each 3D point (although for some I already have it solved), or 2) make residuals bigger by grouping all the points that will use the same problem 2 and compute a residual for all the points with the same problem 2 at once.

I do not understand what you are trying to say here. Could you be more precise in your description.
 
I can do as in 1) and add a residual block for each 3D point, however, solving problem 2 is time-consuming. When I try to do it as in 2), I want to do something like:

ceres::CostFunction* cost_function = new ceres::NumericDiffCostFunction<func,ceres::CENTRAL, n_pts, 4>(new func(point));

Obviously func and point are propperly defined and their type match, n_pts is an integer. However, when I compile I get the following error:

If you are worried about performance, why are you doing numerical differentiation?

Also I hope you are not numerically differentiating the inner solve. That would make things extremely slow.  You can evaluate the derivative of the optimal value function or of the optimal parameter estimates by doing sensitivity analysis.

Sameer

 

the value of 'n_pts' is not usable in a constant expression ceres::CostFunction* cost_function = new ceres::NumericDiffCostFunction<func,ceres::CENTRAL, n_pts, 4>

note: 'n_pts' was not initialized with a constant expression int n_pts(10);


Any idea on how can I make the cos_function variable in size on runtime?


Thank you.


Cheers!

--
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/5fac85d6-934c-428a-bcf1-456ca70d9784%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Albert Palomer

unread,
Sep 20, 2016, 4:02:30 AM9/20/16
to ceres-...@googlegroups.com
Thank you Adita and Sameer for your reply. Addressing Sameer's questions:

1- If I understand your problem, you have a two stage optimization, where the residual of one stage depends on the optimal value of the second optimization problem.
Yes.

2- I do not understand what you are trying to say here. Could you be more precise in your description. 
The solution of the second optimization is common to many observations (each observation is size 3 since it is a 3D point). To solve the first optimization, I could either 1) add a residual block of size 3 for each point, or 2) add a residual block of size 3*n, beeing n the number of points that share the same second optimization. If I do the first, I wold end up solving the second optimization many times with the same initial values and the same final result. If I can do the second, I could compute the second optimization problem only once per group of points.

3- If you are worried about performance, why are you doing numerical differentiation?
If you could point me to how to get the jacobian of the solution of an optimization problem I could change NumericDiffCostFunction (although that I've seen that if I want the number of residuals to not be known at compiling time I should use DynamicNumericDiffCostFunction)  to CostFunction. However, I do not know how to make its size unknown at compiling time. Every time I've used CostFunction I already knew the residuals size.

Thank you very much.


Albert Palomer Vila

To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver+unsubscribe@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+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/CABqdRUBNL8q%3DGacpY336%2Bg3A_3b23DLFTBp-9mb2WTCmDCUACg%40mail.gmail.com.

Sameer Agarwal

unread,
Sep 20, 2016, 8:04:45 AM9/20/16
to ceres-...@googlegroups.com
Albert,
Thanks for explaining your problem. More comments and questions inline.

On Tue, Sep 20, 2016 at 1:02 AM Albert Palomer <alber...@gmail.com> wrote:
Thank you Adita and Sameer for your reply. Addressing Sameer's questions:

1- If I understand your problem, you have a two stage optimization, where the residual of one stage depends on the optimal value of the second optimization problem.
Yes.

2- I do not understand what you are trying to say here. Could you be more precise in your description. 
The solution of the second optimization is common to many observations (each observation is size 3 since it is a 3D point). To solve the first optimization, I could either 1) add a residual block of size 3 for each point,

do you mean as an optimization problem on its own, or do you mean to the top level optimization problem? my understanding is that you are creating a ceres::Problem object inside each cost function and calling Solve on it for these small 3x3 problems?
 
or 2) add a residual block of size 3*n, beeing n the number of points that share the same second optimization. If I do the first, I wold end up solving the second optimization many times with the same initial values and the same final result. If I can do the second, I could compute the second optimization problem only once per group of points.

I still do not understand this.
 

3- If you are worried about performance, why are you doing numerical differentiation?
If you could point me to how to get the jacobian of the solution of an optimization problem I could change NumericDiffCostFunction (although that I've seen that if I want the number of residuals to not be known at compiling time I should use DynamicNumericDiffCostFunction)  to CostFunction. However, I do not know how to make its size unknown at compiling time. Every time I've used CostFunction I already knew the residuals size.

If the number of parameter blocks is constant, but the number of residuals is unknown at compile time, you can still use AutoDiffCostFunction, if the number of parameter blocks is not fixed, then use DynamicAutoDiffCostFunction.

I think it would help to have a mathematical description of your problem.

Sameer


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_OrWUfw-2GPXXW0NLHgzpio5y0LGmZ8bdpHnfaw8hy3KSnQ%40mail.gmail.com.

Albert Palomer

unread,
Sep 20, 2016, 12:04:06 PM9/20/16
to ceres-...@googlegroups.com
Let me try to rephrase the problem:

I have a model with several elements that produce 2D surfaces S in the 3D space (for instance a cone). This model has two sets of parameters. Set A is the set of invariant parameters that I want to estimate using the least squares, and set B is a set of known parameters that change during the problem. When I produce the 3D point clouds that I use to fit the model M I change the B parameters. For each set of parameters B_k I have several 3D points (p_{k_1}...p_{k_n}\in P_ksampled on the surface S_k. The problem that I want to solve is to estimate the set of parameters A that minimize the error function between all the 3D points and its surface generated using the known B_k parameters (for each B_k there is a set of points P_k, and each P_k set of points has different number of points in it). This is what I've been calling problem 1.
The process of estimating the surface S_k from the set of parameters B_k and A is another non-linear least squares problem by itself. This is what I've been calling problem 2. To be able to compute each 3D point error, I need to estimate all the surfaces S_k (each one of which depends on the set of parameters B_k and the parameters beeing optimized in problem 1).
To solve problem 1, I see two options:
1) Add a residual block for each 3D point of size 3.
2) Add a residual block for each P_k set of points of size 3*n.
The total residual block of both options will have the same size. I see the following advantages and disadvantages of each way:
1) Since each residual block is a different instantiation of the cost function, the surface S_k will be computed for each 3D point at each step of the minimizing process of problem 1(meaning that the same surface S_k will be computed as many times as points within P_k). 
2) Since all the points P_k that use the same S_k are in the same instance of the cost function S_k will be computed only once each iteration (once for each set of parameters B_k). Which is obviously preferable to option 1).
(obviously, cost function for solution 1) and 2) are different).

I think the way to go is using option 2 (add a residual block for each P_k set of points of size 3*n) since I will avoid solving many times the same problem 2. Having this in mind, I have two questions:

1) How can I change the residual block size at run time? My problem has a fix parameter block size (number of elements in A) and an unknown residual size. Could you point to some example?
2) How can I avoid using numeric differentiation for problem 1 (I can not template how problem 2 is solved since it is already an optimization problem on its own)? Is there a way to evaluate the jacobian of the problem 2 at the solution so I can compute manually the jacobian of each residual block in problem 1? Could you point to some example?

Thank you very much.


Albert Palomer Vila

To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver+unsubscribe@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+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
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.

--
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/CABqdRUA8Mxq5qd2V5Bh3JnHYB3nYMraAVmcFdteCYaF_T-nLoA%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages