MatrixXd::Index
时间: 2023-09-14 07:08:48 浏览: 59
MatrixXd::Index 是 Eigen 库中的一个类型,用于表示矩阵的索引值。Eigen 是一个 C++ 的线性代数库,提供了各种矩阵和向量操作的功能。MatrixXd 表示动态大小的矩阵,而 Index 是 Eigen 中定义的整数类型,用于表示矩阵的索引值。它通常用于访问和操作矩阵中的元素。
相关问题
它的具体实现是这样的,再详细解释一下 bool Spline2dConstraint::Add2dBoundary( const std::vector<double>& t_coord, const std::vector<double>& angle, const std::vector<Vec2d>& ref_point, const std::vector<double>& longitudinal_bound, const std::vector<double>& lateral_bound) { if (t_coord.size() != angle.size() || angle.size() != ref_point.size() || ref_point.size() != lateral_bound.size() || lateral_bound.size() != longitudinal_bound.size()) { return false; } Eigen::MatrixXd affine_inequality = Eigen::MatrixXd::Zero(4 * t_coord.size(), total_param_); Eigen::MatrixXd affine_boundary = Eigen::MatrixXd::Zero(4 * t_coord.size(), 1); for (uint32_t i = 0; i < t_coord.size(); ++i) { const double d_lateral = SignDistance(ref_point[i], angle[i]); const double d_longitudinal = SignDistance(ref_point[i], angle[i] - M_PI / 2.0); const uint32_t index = FindIndex(t_coord[i]); const double rel_t = t_coord[i] - t_knots_[index]; const uint32_t index_offset = 2 * index * (spline_order_ + 1); std::vector<double> longi_coef = AffineCoef(angle[i], rel_t); std::vector<double> longitudinal_coef = AffineCoef(angle[i] - M_PI / 2, rel_t); for (uint32_t j = 0; j < 2 * (spline_order_ + 1); ++j) { // upper longi affine_inequality(4 * i, index_offset + j) = longi_coef[j]; // lower longi affine_inequality(4 * i + 1, index_offset + j) = -longi_coef[j]; // upper longitudinal affine_inequality(4 * i + 2, index_offset + j) = longitudinal_coef[j]; // lower longitudinal affine_inequality(4 * i + 3, index_offset + j) = -longitudinal_coef[j]; } affine_boundary(4 * i, 0) = d_lateral - lateral_bound[i]; affine_boundary(4 * i + 1, 0) = -d_lateral - lateral_bound[i]; affine_boundary(4 * i + 2, 0) = d_longitudinal - longitudinal_bound[i]; affine_boundary(4 * i + 3, 0) = -d_longitudinal - longitudinal_bound[i]; } // std::cout << affine_inequality << std::endl; return AddInequalityConstraint(affine_inequality, affine_boundary); }
这段代码实现了 `Spline2dConstraint` 类的成员函数 `Add2dBoundary`。函数的目的是添加一个二维边界约束到约束对象中。
首先,函数会检查传入的参数的大小是否一致,如果不一致,则会返回 `false`,表示添加失败。
接下来,函数会初始化两个 `Eigen::MatrixXd` 类型的矩阵 `affine_inequality` 和 `affine_boundary`,用于存储边界约束的系数和边界值。
然后,函数会遍历传入的 `t_coord`(曲线参数)、`angle`(角度)、`ref_point`(参考点)、`longitudinal_bound`(纵向边界)和 `lateral_bound`(横向边界)这些数组。
在循环中,首先计算参考点到曲线的正交距离 `d_lateral` 和纵向距离 `d_longitudinal`,然后根据曲线参数 `t_coord[i]` 找到对应的索引,并计算相对参数 `rel_t`。
接下来,函数会调用 `AffineCoef` 函数获取曲线的系数。
随后,函数会将系数填充到 `affine_inequality` 矩阵中,为上下限约束的系数赋值。
同时,函数还将边界值与距离值进行比较,并将结果填充到 `affine_boundary` 矩阵中,作为上下限约束的边界值。
最后,函数调用 `AddInequalityConstraint` 函数,将生成的约束矩阵和边界矩阵添加到约束对象中。
最后,函数返回 `AddInequalityConstraint` 的返回值,表示约束是否成功添加。
注意:在代码中还有一行注释掉的代码 `// std::cout << affine_inequality << std::endl;`,该行代码可以打印出生成的约束矩阵 `affine_inequality` 的值,用于调试目的。
Eigen::ArrayXXd windows(D * H * W * anchors.size(), 6); //Eigen::MatrixXd windows(D * H * W * anchors.size(), 6); int index = 0; Eigen::VectorXd oz(D), oh(H), ow(W); for (int z = 0; z < D; ++z) { oz[z] = offset + z * stride; } for (int y = 0; y < H; ++y) { oh[y] = offset + y * stride; } for (int x = 0; x < W; ++x) { ow[x] = offset + x * stride; } // 计算 anchor box 的坐标 for (int z = 0; z < D; ++z) { for (int y = 0; y < H; ++y) { for (int x = 0; x < W; ++x) { for (int a = 0; a < anchors.size(); ++a) { windows.row(index) << oz[z], oh[y], ow[x], anchors[a][0], anchors[a][1], anchors[a][2]; ++index; } } } } return windows;用eigen内部的方法重新写一下,减低循环复杂度
可以使用 Eigen::Tensor 代替循环实现计算所有 anchor boxes 的位置和大小。具体实现如下:
```
Eigen::Tensor<double, 2> oz = (Eigen::Tensor<double, 1>(D) * stride + offset).reshape(D, 1);
Eigen::Tensor<double, 2> oh = (Eigen::Tensor<double, 1>(H) * stride + offset).reshape(1, H);
Eigen::Tensor<double, 2> ow = (Eigen::Tensor<double, 1>(W) * stride + offset).reshape(1, 1, W);
Eigen::Tensor<double, 3> anchors_tensor(1, anchors.size(), 3);
for (int a = 0; a < anchors.size(); ++a) {
anchors_tensor(0, a, 0) = anchors[a][0];
anchors_tensor(0, a, 1) = anchors[a][1];
anchors_tensor(0, a, 2) = anchors[a][2];
}
Eigen::Tensor<double, 3> oz_tensor = oz.broadcast(Eigen::array<Eigen::Index, 3>({ 1, H, W }));
Eigen::Tensor<double, 3> oh_tensor = oh.broadcast(Eigen::array<Eigen::Index, 3>({ D, 1, W }));
Eigen::Tensor<double, 3> ow_tensor = ow.broadcast(Eigen::array<Eigen::Index, 3>({ D, H, 1 }));
Eigen::Tensor<double, 4> windows_tensor = Eigen::Tensor<double, 4>(D, H, W, anchors.size(), 6);
windows_tensor.chip(0, 3) = oz_tensor.reshape(D, H, W, 1).broadcast(Eigen::array<Eigen::Index, 4>({ 1, 1, 1, anchors.size() }));
windows_tensor.chip(1, 3) = oh_tensor.reshape(D, H, W, 1).broadcast(Eigen::array<Eigen::Index, 4>({ 1, 1, 1, anchors.size() }));
windows_tensor.chip(2, 3) = ow_tensor.reshape(D, H, W, 1).broadcast(Eigen::array<Eigen::Index, 4>({ 1, 1, 1, anchors.size() }));
windows_tensor.chip(3, 3) = anchors_tensor.broadcast(Eigen::array<Eigen::Index, 4>({ D, H, W, 1 }));
windows_tensor.chip(4, 3) = anchors_tensor.broadcast(Eigen::array<Eigen::Index, 4>({ D, H, W, 1 })).chip(0, 2) * anchors_tensor.broadcast(Eigen::array<Eigen::Index, 4>({ D, H, W, 1 })).chip(0, 2) / anchors_tensor.broadcast(Eigen::array<Eigen::Index, 4>({ D, H, W, 1 })).chip(0, 1);
windows_tensor.chip(5, 3).setConstant(0.5);
Eigen::ArrayXXd windows = windows_tensor.reshape(D * H * W * anchors.size(), 6).shuffle(Eigen::array<int, 2>({ 1, 0 })).matrix();
```
这段代码首先使用 Eigen::Tensor 构造 oz、oh 和 ow 三个张量,分别表示 D、H 和 W 个方向上 anchor boxes 的中心坐标。然后,代码使用 anchors 数组构造一个张量 anchors_tensor,用于表示所有 anchor boxes 的宽高和宽高比。
接下来,代码使用 broadcast() 方法将 oz、oh 和 ow 三个张量分别扩展到与 anchors_tensor 相同的维度。然后,代码使用 chip() 方法将扩展后的张量拼接成一个四维张量 windows_tensor,其中第四维有 6 个元素,分别表示中心坐标和宽高比。最后,代码使用 reshape() 和 shuffle() 方法将 windows_tensor 转换成一个二维矩阵 windows,并返回该矩阵。
相比于原来的循环实现,使用 Eigen::Tensor 的实现方式可以减少循环嵌套的层数,提高计算效率。
相关推荐
![docx](https://img-home.csdnimg.cn/images/20210720083331.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)