<Eigen::VectorXd>对象存取

缘由

最近在跑实验的时候,遇到一个需求,就是将一个vector<Eigen::VectorXd>的对象存到本地文件中,然后在需要使用的时候,再读取出来。

由于感觉不是很难,所以没有到网上找资料自己写,直接喂给了chatgpt。然后chatgpt给我返回了下面的代码。

Chatgpt版本代码

void saveToFile(const std::vector<Eigen::VectorXd>& data, const std::string& filename) {
    std::ofstream outFile(filename);
    if (!outFile) {
        std::cerr << "Error opening file for writing: " << filename << std::endl;
        return;
    }

    outFile << data.size() << std::endl;

    for (const auto& vec : data) {
        outFile << vec.size() << std::endl;
        for (int i = 0; i < vec.size(); ++i) {
            outFile << vec(i) << (i < vec.size() - 1 ? " " : ""); // 使用空格分隔
        }
        outFile << std::endl; // 每个向量后换行
    }

    outFile.close();
}

std::vector<Eigen::VectorXd> loadFromFile(const std::string& filename) {
    std::ifstream inFile(filename);
    if (!inFile) {
        std::cerr << "Error opening file for reading: " << filename << std::endl;
        return {};
    }
    std::vector<Eigen::VectorXd> data;
    size_t numVectors;
    inFile >> numVectors;
    for (size_t i = 0; i < numVectors; ++i) {
        size_t vecSize;
        inFile >> vecSize;
        Eigen::VectorXd vec(vecSize);
        for (size_t j = 0; j < vecSize; ++j) {
            inFile >> vec(j);
        }
        data.push_back(vec);
    }
    inFile.close();
    return data;
}

咋一看感觉确实没毛病,写了一个简单的测试函数,输入常规的数据,发现存取的数据是”肉眼“一致的。(记住这里的”肉眼“一致)

看起来没啥问题就用了,但是我发现实验结果总是不太对,和正常的结果差了不少。本来是没怀疑这两个函数的,毕竟”肉眼“一致的。但是我仔仔细细查了其它部分的代码,虽然找到了一些数据读取上的bug,但是改了之后还是没有正常。

本来打算放弃不找了,但是又想试试不存取数据的方案,然后就发现不存取数据,结果正常了。这个时候我就认定上面的两个函数有问题了。

可以,它两”肉眼“正确,我也没多怀疑。不过,我的师弟知道这件事情后来了兴致,想要好好看看。经过师弟的一番折腾,还真发现了问题。

师弟的代码(正确的代码)

void saveToFileV2(const std::vector<Eigen::VectorXd>& data, const std::string& filename) {
    std::ofstream outFile(filename,std::ios::binary);
    if (!outFile) {
        std::cerr << "Error opening file for writing: " << filename << std::endl;
        return;
    }

    size_t numVectors = data.size();
    outFile.write(reinterpret_cast <const char*> (&numVectors),sizeof (numVectors));

    for (const auto& vec : data) {
        size_t vecSize = vec.size();
        outFile.write(reinterpret_cast <const char*> (&vecSize),sizeof (vecSize));
        for (int i = 0; i < vec.size(); ++i) {
            outFile.write(reinterpret_cast <const char*> (&vec[i]),sizeof (double));
//            outFile << vec(i) << (i < vec.size() - 1 ? " " : ""); // 使用空格分隔
        }
//        outFile << std::endl; // 每个向量后换行
//        outFile.write(reinterpret_cast <const char*> (vec.data()),vecSize * sizeof (double));
    }

    outFile.close();
}

std::vector<Eigen::VectorXd> loadFromFileV2(const std::string& filename) {
    std::ifstream inFile(filename,std::ios::binary);
    if (!inFile) {
        std::cerr << "Error opening file for reading: " << filename << std::endl;
        return {};
    }
    std::vector<Eigen::VectorXd> data;
    size_t numVectors;
//    inFile >> numVectors;
    inFile.read(reinterpret_cast<char *>(&numVectors),sizeof (numVectors));
    for (size_t i = 0; i < numVectors; ++i) {
        size_t vecSize;
//        inFile >> vecSize;
        inFile.read(reinterpret_cast<char *>(&vecSize),sizeof (vecSize));
        Eigen::VectorXd vec(vecSize);
//        inFile.read(reinterpret_cast<char *>(vec.data()),vecSize * sizeof (double ));
        for (size_t j = 0; j < vecSize; ++j) {
//            inFile >> vec(j);
            inFile.read(reinterpret_cast <char*> (&vec[j]),sizeof (double));
        }
        data.push_back(vec);
    }
    inFile.close();
    return data;
}

师弟说我之前的代码存的数据是以文本形式存储,对于高精度的数据来说,在存取的过程中可能损失精度。所以,他改了存储方式,将数据以二进制形式存储,这样的话,精度就不会损失,可以保证每一位都一致。

师弟说得很有道理,对于高精度数据来说,必须要用二进制形式存储,否则的话,精度损失很严重。不过,如果精度要求比较低或者说是常规的整数数据,还是可以用原来的代码存取。

总结

对于存取vector<Eigen::VectorXd>类型的数据,还是建议用后面版本的代码。同时,如果说是其它类型的数据,也推荐存为二进制,而不是文本,否则可能出现问题。

最后,感谢师弟的钻研精神,也感谢师弟帮我远程配置实验环境!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值