我正在将一个matlab程序移植到C / C ++中。我有几个问题,但其中一个最重要的问题是:Matlab处理任何维度相同的数组。假设我们有这样的函数,
function result = f(A, B, C)
result = A + 2 * B + C;
A , B 和 C 可以是任何尺寸/大小的数组。我不是C / C ++专业版,但我想这不是一个简单的& C中的干净工作。一个想法是使用void指针将数组传递给函数。那么尺寸和数组运算(+ / *)呢? 另一个想法是使用C ++类。我或许可以编写一个模板类,其中包含所有必需的数组操作,例如(*,+,<<,>>,...)。但我相信这将是一项令人筋疲力尽的工作。有没有人有更好的主意?任何支持+和*运算符的简单/多维/单头文件/ opensource数组类?
答案 0 :(得分:3)
你可以看一下boost :: ublas库。它支持向量,矩阵,线性代数等。
答案 1 :(得分:3)
我建议使用Armadillo。对于Matlab用户,文档甚至都有syntax conversion table。
答案 2 :(得分:3)
我建议你使用C ++类。当然不要自己实现这些类。有人在这样的任务中做得很好。 @Darrem建议嘘声:: ublas。我建议eigen。它具有更多的功能,ublas,它维护得很好,它支持大量的编译器及其性能,它比英特尔MKL等专有库更接近有时更好。
答案 3 :(得分:0)
由于答案不适合我,我自己上了课。这堂课适合我。但我很确定它不是为C ++而设计的。它还可能导致内存泄漏。如果您发现问题,请给我留言。如果我制作新版本以保持答案对其他人有用,我会升级代码。顺便说一下,这个类现在适用于1,2和3维,但它可以很容易地扩展到任意数量的维度。这是代码,
#ifndef XARRAY_H_INCLUDED
#define XARRAY_H_INCLUDED
#include <string>
#include <sstream>
#include <vector>
#include <assert.h>
using namespace std;
template <class T = double>
class XArray
{
// Fields (keep data)
int index_helper[10];
// cells of the array
vector<T> table;
// dimensions of the array
vector<int> dims;
public:
XArray(){}
XArray(unsigned int n, int *d)
{
dims.resize(n);
int size = 1;
for (unsigned int i = 0; i < n; i++) {
size *= d[i];
dims[i] = d[i];
}
table.resize(size);
}
XArray(unsigned int d1)
{
dims.resize(1);
dims[0] = d1;
table.resize(d1);
}
XArray(unsigned int d1, unsigned int d2)
{
dims.resize(2);
dims[0] = d1;
dims[1] = d2;
table.resize(d1 * d2);
}
XArray(unsigned int d1, unsigned int d2, unsigned int d3)
{
dims.resize(3);
dims[0] = d1;
dims[1] = d2;
dims[2] = d3;
table.resize(d1 * d2 * d3);
}
XArray(const XArray<T>& xa)
{
this->table = xa.table;
this->dims = xa.dims;
}
int dim(int i)
{
return dims[i];
}
int num_dims()
{
return dims.size();
}
T& operator()(int i)
{
index_helper[0] = i;
return get_helper(1, index_helper);
}
T& operator()(int i, int j)
{
index_helper[0] = i;
index_helper[1] = j;
return get_helper(2, index_helper);
}
T& operator()(int i, int j, int k)
{
index_helper[0] = i;
index_helper[1] = j;
index_helper[2] = k;
return get_helper(3, index_helper);
}
XArray<T> operator*(double m)
{
XArray<T> r = *this;
for (unsigned int i = 0; i < table.size(); i++) {
r.table[i] *= m;
}
return r;
}
XArray<T> operator/(double m)
{
XArray<T> r = *this;
for (unsigned int i = 0; i < table.size(); i++) {
r.table[i] /= m;
}
return r;
}
XArray<T> operator+(const XArray<T> &that)
{
assert(this->dims.size() == that.dims.size());
for (unsigned int i = 0; i < dims.size(); i++) {
assert(this->dims[i] == that.dims[i]);
}
XArray<T> r = *this;
for (unsigned int i = 0; i < table.size(); i++) {
r.table[i] += that.table[i];
}
return r;
}
XArray<T> operator-(const XArray<T> &that)
{
assert(this->dims.size() == that.dims.size());
for (unsigned int i = 0; i < dims.size(); i++) {
assert(this->dims[i] == that.dims[i]);
}
XArray<T> r = *this;
for (unsigned int i = 0; i < table.size(); i++) {
r.table[i] -= that.table[i];
}
return r;
}
private:
T& get_helper(unsigned int n, int *indices)
{
assert(n == dims.size());
int multiplier = 1;
int index = 0;
for (unsigned int i = 0; i < n; i++) {
//cerr << "index " << i << " out of range. Expected [0, " << dims[i] - 1
// << "] found " << indices[i] << endl;
assert(indices[i] >= 0 && indices[i] < dims[i]);
index += indices[i] * multiplier;
multiplier *= dims[i];
}
return table[index];
}
};
template <class T>
ostream &operator<<(ostream &stream, XArray<T> xa)
{
int d = xa.num_dims();
if(d == 1)
{
int n = xa.dim(0);
for(int i = 0; i < n; i++)
{
stream << xa(i);
if(i < n - 1)
{
stream << ", ";
}
}
}
else
{
stream << "XArray[";
for(int i = 0; i < d; i++)
{
stream << xa.dim(i);
if(i < d - 1)
{
stream << "x";
}
}
stream << "]";
}
return stream;
}
#endif // XARRAY_H_INCLUDED