> For the complete documentation index, see [llms.txt](https://ceres-solver-tutorial-cn.gitbook.io/ceres/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ceres-solver-tutorial-cn.gitbook.io/ceres/modeling-non-linear-least-squares/main-class-interface/costfunction.md).

# CostFunction

对于目标函数中的每个项，都有一个`CostFunction` 负责计算残差向量和 Jacobian 矩阵。考虑其中一项残差 $$f(x\_1,x\_2,...,x\_k)$$ ，其取决于参数块 $$\[x\_1,x\_2,...,x\_k]$$。给定参数 $$\[x\_1,x\_2,...,x\_k]$$，`CostFunction` 负责计算向量函数 $$f(x\_1,x\_2,...,x\_k)$$ 和它对每个变量的 Jacobian 矩阵。

$$
J\_i=D\_if(x\_1,...,x\_k) \ \forall \in {1,...,k}
$$

```cpp
class CostFunction
```

Code Impl

```cpp
class CostFunction {
 public:
  virtual bool Evaluate(double const* const* parameters,
                        double* residuals,
                        double** jacobians) const = 0;
  const std::vector<int32>& parameter_block_sizes();
  int num_residuals() const;

 protected:
  std::vector<int32>* mutable_parameter_block_sizes();
  void set_num_residuals(int num_residuals);
};
```

`CostFunction` 输入参数块的数量和大小以及输出的数量分别存储在 `CostFunction::parameter_block_sizes_` 和 `CostFunction::num_residuals_`中。从该类继承的用户代码应使用相应的函数方法设置这两个成员。当使用 `Problem::AddResidualBlock()` 添加时，`Problem` 将验证这些信息。

```cpp
bool CostFunction::Evaluate(double const *const *parameters, 
                            double *residuals, 
                            double **jacobians) const
```

上述函数用于计算残差向量和 Jacobian 矩阵。该函数为纯虚函数，需要在子类进行重写，因为 Ceres 不知道你的残差是如何计算的。对其中的参数做出一些解释和强调。

* `parameters` 是一个数组，其大小为 `CostFunction::parameter_block_sizes_.size()`。
* `parameters[i]` 也是一个数组，其大小为 `CostFunction::parameter_block_sizes_[i]`
* 从上面了两条可以看出 `parameters` 其实是一个二维数组。
* `parameters` 永远不能为 `nullptr`。
* `residuals` 是一个数组，长度为 `num_residuals`。
* `residuals` 永远不能为 `nullptr`。
* `jacobians` 是一个数组，长度为 `CostFunction::parameter_block_sizes_.size()`。
* `jacobians[i]` 是一个 row-major 数组，长度为 `num_residuals x parameter_block_sizes_[i]`。
* 如果 `jacobians[i]` 不为 `nullptr` 的话，需要用户手动计算残差相对于 `parameters[i]` 的 Jacobian 矩阵，并存储在数组中，例如 `jacobians[i][r * parameter_block_sizes_[i] + c]` = $$\frac{\partial \text{residual\[r]}}{\partial \text{paramters\[i]\[c]}}$$。
* 如果 `jacobians[i]` 为 `nullptr`，那么它的计算过程可以跳过，这种情况发生在当参数块被设定为常数的时候。
* 返回值表示残差和 Jacobian 的计算是否成功。这可用于检查 jacobian 计算中是否有数值问题。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ceres-solver-tutorial-cn.gitbook.io/ceres/modeling-non-linear-least-squares/main-class-interface/costfunction.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
