如何用NaN元素初始化双矩阵?

How to initialize double matrix with NaN element?

本文关键字:初始化 何用 NaN 元素      更新时间:2023-10-16

在我的代码中,我有一个像这样的双精度矩阵:

double * * matrix=new double * [10];
for(int i=0;i<10;i++) 
matrix[i]=new double[10];

我想在初始化该矩阵的每个单元格中都有NaN 值,是否可以自动执行或唯一的解决方案是:

for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
matrix[i][j]=nan("");

是否可以推断,当矩阵将构建时,它不使用双倍插入的默认构造函数,对于每个矩阵[i][j],0.0 值,但插入 nan("(?

double

没有默认的构造函数,即 默认情况下,double值未初始化。

要避免显式实现循环,可以使用std::vector

#include <vector>
...
std::vector<std::vector<double>> matrix(10, std::vector<double>(10, nan("")));

或:

#include <vector>
using namespace std;
...
vector<vector<double>> matrix(10, vector<double>(10, nan("")));

首先,强烈避免在C++自己时使用原始指针 - 这几乎总是一个坏主意。如果没有合适的容器类,请使用std::unique_ptr。因此,您的代码变为:

auto matrix = std::make_unique<double* []>(10);
for(int i=0;i<10;i++)  {
matrix.get()[i]= std::make_unique<double []>(10);
}

这段代码仍然不是你想要的。使用N个调用new或向量的n个构造来创建NxN矩阵通常不是一个好主意。对 NxN 双精度进行单次分配,然后将其包装在支持 2 参数方括号运算符的类MyMatrix中,即

template <typename T>
class MyMatrix { 
// etc. etc
double const T& operator[](size_type i, size_type j) const { return data_[i*n + j]; }
double T& operator[](size_type i, size_type j) { return data_[i*n + j]; }
}

或者(不推荐(让指针指向单个分配区域:

size_t n = 10;
auto matrix_data = std::make_unique<double []>(n * n);
auto matrix = std::make_unique<double* []>(n);
for(int i=0;i<10;i++)  {
matrix.get()[i] = matrix_data.get() + i * n;
}

在上述每种情况下,您以后都可以使用std::fill在任何循环之外将所有矩阵值设置为 NaN。

上面的最后一个示例也可以转换为使用向量(如果您不使用自己的类,这可能比原始指针更好(:

size_t n = 10;
auto matrix_data = std::vector<double>(n * n);
auto matrix = std::vector<double*>(n);
for(auto& row : matrix) {
auto row_index = std::dist(row, matrix.begin());
row = &matrix_data[row_index * n];
}

同样,我不建议这样做 - 它仍然是一种类似 C 的方式来启用my_matrix[i][j]语法,而使用包装类可以让您my_matrix[i,j]而无需额外的存储空间,初始化为 NaN 或其他值(在构造函数中(,并且每次访问它时都不会遵循两个指针。

如果你想使用静态大小的数组,你最好使用std::array。为了更轻松地使用多维std::array可以使用模板别名

template <class T, size_t ROW, size_t COL>
using Matrix = std::array<std::array<T, COL>, ROW>;

您可以使用std::array::fill设置矩阵中的值,例如

Matrix<double, 3, 4> m = {};
m.fill(42.0);

还可以创建使用默认值初始化的编译时常量矩阵对象,以使用简单的constexpr函数在运行时跳过初始化。

template<typename T, size_t R, size_t C>
constexpr auto makeArray(T&& x) {
Matrix<T,R,C> m = {};
for(size_t i=0; i != R; ++i) {
for(size_t j=0; j != C; ++j) {
m[i][j] = std::forward<T>(x);
}
}
return m;
}
auto constexpr m = makeArray<double, 3,4>(23.42);

我将重复给出的建议,即更喜欢C++构造而不是 C 构造。它们更类型安全,恕我直言,使用起来几乎总是更方便,例如,std::array对象作为参数传递与任何其他对象没有什么不同。如果你来自C背景,没有进一步C++经验,我建议阅读一些没有首先介绍C的教程文本,例如C++之旅,