Matlab在c ++中重塑

时间:2014-04-17 11:36:02

标签: c++ c arrays matlab reshape

在Matlab中,可以重塑'从任何维度到任何其他维度的(N维)矩阵,只要元素的数量不变。那就是:

A = rand(10,10);
B = reshape(A, 100, 1);

Matlab可以非常高效地完成这项任务,因为A和B仍指向100个双打的同一个块,只有在写入A或B时才复制它们:这称为写时复制。

我想在C / C ++中使用这种重塑功能,也就是说,我希望能够做到这一点:

double flat[100];
double square[10][10] = ... flat ...;

这样,square代表相同的数据,但解释器以另一种方式索引。

最后,我想要的是语法糖,做square [i] [j]而不是square [10 * i + j]。所以,是的,编写一些能够与不同维度共享数据的类(如matlab一样)重载索引运算符可以做yob。但是,我正在寻找一个更简单的解决方案。

另一方面,我担心C ++标准允许编译器以不同的方式实现维数阵列,不允许我想要的东西。例如,int [10] [10]可以实现为10个双精度的10个块和10个指向那些的双指针的一个块。而且,我自己可以创造这样的东西:

double **blowUp(double *array, int m, int n) {
    double **r = new double[m];
    for(int i=0; i<m; ++i, array+=n) r[i] = array;
    return r;
}

然后语法糖的想法消失了一点,特别是因为我还需要清理包装器数组。

另一种解决方案可能是模板化的下标运算符重载,其中模板参数包含数据的第一维:

http://ideone.com/aonHN2

但是,正如编译错误所示,如果不将数据包装在类结构中,这是不可行的。所以,如果我想要我想要的东西,我注定要在一个类中包装数据并编写很多样板代码吗?请让我知道你的想法!

2 个答案:

答案 0 :(得分:4)

如果你使用的是一个简单的数组,使用reinterpret_cast就很容易了。举个例子:

#include <iostream>

int main()
{
    int flat[100];
    for (int i=0; i<100; ++i)
        flat[i]=i;
    // now reinterpret that flat array as a 10x10 square
    int (&square)[10][10] = *reinterpret_cast<int(*)[10][10]>(flat);
    // print an arbitrary row
    for (int i=0; i<10; ++i)
        std::cout << square[5][i] << ' ';
    std::cout << '\n';
}

这个简单的程序打印:

50 51 52 53 54 55 56 57 58 59 

答案 1 :(得分:2)

最简单的方法是将平面数组包装在一个类中。您可以实现use operator[]以返回指向i th 行的指针。此operator[]的实现需要知道您希望对基础数组施加的形状。