【问题标题】:Expression must have constant value Eigen matrix表达式必须具有常数值特征矩阵
【发布时间】:2016-10-18 01:37:53
【问题描述】:

我一直在尝试通过函数在运行时给出矩阵大小,例如

Eigen::MatrixXd FileReader::load_csv(const std::string & path, const int rows_csv, const int columns_csv) {
    std::ifstream indata;
    indata.open(path);
    std::string line;
    std::vector<double> values;
    int rows = 0;
    while (getline(indata, line)) {
        std::stringstream lineStream(line);
        std::string cell;
        while (std::getline(lineStream, cell, ',')) {
            values.push_back(std::stod(cell));
        }
        ++rows;
    }
    std::cout << "loading";
    return Eigen::Map<const Eigen::Matrix<double, columns_csv, rows_csv, Eigen::RowMajor>>(values.data(), rows, values.size() / rows);
}

(以上代码来自https://stackoverflow.com/a/39146048/3782963),我无法将矩阵大小的常量值发送给函数,我收到Expression must have constant value 错误。有什么办法可以做这样的事情:

Eigen::MatrixXd mat = load_csv("some_path", 20, 30);

有什么想法吗?

【问题讨论】:

    标签: c++ matrix eigen


    【解决方案1】:

    这一行是你的问题:

    Eigen::Map<const Eigen::Matrix<double, columns_csv, rows_csv, Eigen::RowMajor>>
                                              (values.data(), rows, values.size() / rows);
    

    Eigen::Map<const Eigen::Matrix<double, columns_csv, rows_csv, Eigen::RowMajor>>
                                               ^^^         ^^^
    

    告诉Map 它应该期望一个恒定大小的矩阵,并且

    (values.data(), rows, values.size() / rows);
                    ^^^              ^^^
    

    是一个动态大小的矩阵。如果由于某种原因,您想忽略文件中矩阵的形状并在程序中定义它,请尝试:

    Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>
                                                     (values.data(), rows_csv, columns_csv);
    

    【讨论】:

    • 您应该使用Eigen::Dynamic 而不是-1,但是(尽管该值不会再次更改)。对于防御性编程,检查每一行是否实际上具有相同数量的条目可能是有意义的。
    • @chtz 更改为 Eigen::Dynamic。至于防御性编程,在 OP 链接的问题中,这将是相关的(如何将 csv 文件读入特征矩阵?)。在这种情况下(据我了解 OP),她/他想要覆盖文件中矩阵的形状,无论它实际上是否是矩形。
    • 但这不是慢吗?如果我使用Eigen::Dynamic,它似乎会占用大量内存。
    • 较慢尚未相关。不能使用变量作为模板参数,需要在编译时解析。此外,如果需要内存,动态或静态不会改变数量,只是分配的位置(堆与堆栈)。
    【解决方案2】:

    阅读Matrix size allocation 上的文档也很有帮助,其中指出:

    固定大小与动态大小:

    固定大小意味着已知的行数和列数是 编译时。在这种情况下,Eigen 分配系数数组 作为一个固定大小的数组,作为一个类成员。这很有意义 小矩阵,通常高达 4x4,有时高达 16x16。较大 矩阵应声明为动态大小,即使碰巧 在编译时知道它们的大小。动态大小意味着数字 在编译时不一定知道行数或列数。在这个 如果它们是运行时变量,则系数数组是 在堆上动态分配。请注意,稠密矩阵,无论是 Fixed-size 或 Dynamic-size,不要在意义上动态扩展 一个标准::地图。如果您想要这种行为,请参阅稀疏模块。

    【讨论】:

      猜你喜欢
      • 2020-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-23
      • 1970-01-01
      • 1970-01-01
      • 2021-01-14
      相关资源
      最近更新 更多