您的位置:首页 > 其它

浅谈多维数组行列布局之间的转换规则

2013-05-20 10:07 405 查看
最近做个项目,需要将行排列的多维数组(如lua、c/c++中)与列排列的多维数组(如matlab、R、Fortune中)进行相互转换。

其实行排列、列排列是个通俗的叫法,严格上说行排列是遍历数组元素时下标从右往左递增的排列,而列排列是下标从左往右的排列。举例:对于int Array[2][2][2],如果按行排列的情况遍历,则为Array[0][0][0],Array[0][0][1],Array[0][1][0],Array[0][1][1],Array[1][0][0],Array[1][0][1],Array[1][1][0],Array[1][1][1];如果按列排列的情况遍历,则为Array[0][0][0],Array[1][0][0],Array[0][1][0],Array[1][1][0],Array[0][0][1],Array[1][0][1],Array[0][1][1],Array[1][1][1]。

如何将lua的一个多维矩阵(行排列)赋值给matlab/R的多维矩阵(列排列)呢?

当然是通过c/c++。毕竟lua、matlab、R等脚本语言都是通过c支持的。另外,在进行矩阵中单个元素赋值的时候,只能通过线性下标的形式。下面给一个思路:

typedef vector<size_t> MATRIX_DIMENSION; // 数组的维度

typedef vector<size_t> MATRIX_INDEX; // 数组下标,遍历数组时使用

MATRIX_DIMENSION mat_dim = ...; // 从lua中读取过来

MATRIX_INDEX subscripts(matrixDim.size(), 0); // 下标从[0][0][0]...开始,线性下标为0

while (subscripts没有遍历完) { // 下标当然是以从右往左的顺序递增

size_t rLinearIndice = calcSingleSubscriptOfRMatrix(mat_dim, subscripts); // 计算subscripts对应的在以列排列的数组中的线性下标

RMatrix[rLinearIndice
] = luaElement;

iterateSubscript(mat_dim, subscripts); // 让下标增一

}

bool iterateSubscript(const MATRIX_DIMENSION &dimensions, MATRIX_INDEX &subscripts)

{

    MATRIX_DIMENSION::const_reverse_iterator it1;

    MATRIX_INDEX::reverse_iterator it2;

    for (it1 = dimensions.rbegin(), it2 = subscripts.rbegin();

        it1 != dimensions.rend() && it2 != subscripts.rend();

        ++it1, ++it2) {

        if (*it2 >= *it1)

            return false;

        if (*it2 < *it1-1) {

            *it2 += 1;

            return true;

        }

        else { // *it2 == *it1 - 1

//            if (it2 == subscripts.rend()-1)

//                return false;

            *it2 = 0;

        }

    }

    return true;

}

// 求以列排列的矩阵中元素的线性下标

size_t calcSingleSubscriptOfRMatrix(const MATRIX_DIMENSION &dimensions, const MATRIX_INDEX &subscripts)

{

    MATRIX_INDEX vecEx;

    size_t temp = 1;

    vecEx.push_back(temp);

    MATRIX_INDEX::const_iterator it1, it2, it3;

    for (it1 = dimensions.begin(); it1 != dimensions.end()-1; ++it1) {

        temp *= *it1;

        vecEx.push_back(temp);

    }

    size_t ret = 0;

    for (it2 = vecEx.begin(), it3 = subscripts.begin();

        it2 != vecEx.end(), it3 != subscripts.end();

        ++it2, ++it3) {

            ret += (*it2) * (*it3);

        }

    return ret;

}

At last: 

希望能对需要的朋友有帮助,同时也是自己对相关知识的一个总结,方便以后用到时回忆。对于这个多维数组行列的转换,小弟还有其它一些方法,要么在时间效率上逊于本方法,要么在空间效率上逊于此,也算是走过的一个弯路,就不写出来了,有兴趣的朋友邮件或qq联系84020702@qq.com。

关于lua、R与c++混合编程的一些技术,以及量化投资技巧,也欢迎与大家讨论

。第一次写博客,且小弟比较喜欢偷懒,写得比较粗略,嘿嘿

,以后会越写越好的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: