You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用非静态变量定义雅可比循环时Ceres-Solver报错求助

Hey there, let's break down the Ceres Solver issue you're facing and walk through the likely causes and fixes:

Key Issue Analysis & Fixes

First, let's start with the most obvious red flag in your code, then move into the trickier runtime problems.

1. Your Jacobian Calculation is Completely Incorrect

Looking at your residual formula:

residuals[0] = d0;
for (int i = 0; i < num_weights; ++i) {
    residuals[0] += parameters[i+1][0];
}

This means the residual is a sum of all parameters (the first d0 plus every weight parameter). The partial derivative of this residual with respect to each parameter is 1, not 0.

Right now you're setting all Jacobian entries to 0:

jacobians[i][0] = 0;

Ceres Solver runs consistency checks by default (comparing your analytical Jacobian to numerical differentiation). When these two results don't match, it throws the "Residual and Jacobian evaluation failed." error.

Fix This First:

Update the Jacobian assignment to:

jacobians[i][0] = 1;

2. _weights.size() Might Be Changing Unexpectedly at Runtime

You mentioned hardcoding num_weights fixes the issue, which suggests that when you use _weights.size() in Evaluate, it's returning a value that doesn't match what was used to set up the parameter blocks in the constructor.

Possible reasons:

  • Memory corruption: Some other part of your code is writing to invalid memory, overwriting the internal state of the _weights vector (e.g., its size counter). Tools like Valgrind can help track this down.
  • Lifetime mismatch: If your Cost objects are being destroyed or deallocated before the solver runs, accessing _weights would lead to undefined behavior. Double-check that all cost objects remain valid for the full duration of the solver's execution.

3. Parameter Block Count vs. Passed Parameters Don't Match

In your constructor, you set up 1 + _weights.size() parameter blocks. If you pass fewer or more parameters when calling AddResidualBlock, Ceres will pass a mismatched number of parameters to Evaluate.

For example:

  • If you construct a Cost with 5 weights (so 6 parameter blocks total), but only pass 5 parameters to AddResidualBlock, accessing parameters[i+1] in your loop will go out of bounds, triggering a runtime error.
  • Hardcoding num_weights might accidentally align with the actual number of parameters passed, avoiding the out-of-bounds access.

Verify This:

Add a debug print after creating your cost object to confirm the parameter block count, then ensure you pass exactly that many parameters to AddResidualBlock:

auto cost_function = new Cost(weights);
std::cout << "Expected parameter blocks: " << cost_function->parameter_block_sizes().size() << std::endl;
// Make sure AddResidualBlock receives this exact number of parameters
problem.AddResidualBlock(cost_function, nullptr, param0, param1, param2, ...);

内容的提问来源于stack exchange,提问作者Jan-Michael Tressler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:25:21