C / C ++:矩阵上的循环移位

时间:2015-02-03 17:27:48

标签: c++ armadillo

我正在尝试编写一个有效的代码来执行循环移位,我需要在数据处理期间在大矩阵上多次实现它。

在我的第一次试用中,编译器抛出一些异常,似乎我可能试图访问超出其大小的矩阵元素,我不知道出错了什么。

1)我还使用Armadillo lib定义了"mat"。 2)我打算按行和/或列移动它。

这是我的尝试:

#include "stdafx.h"
#include <vector>
#include <iostream>
#include "C:\Users\kumar\Documents\Visual Studio 2012\UserLibs\armadillo-3-910-0\include\armadillo"

#include <stdlib.h>     /* srand, rand */
using namespace arma;



template<class ty>
void circshift(ty *out, const ty *in, int xdim, int ydim, int xshift, int yshift)
{

    int iOutputInd, iInputInd, ii, jj;

    for (int i =0; i < xdim; i++) 
    {
        ii = (i + xshift) % xdim;
        for (int j = 0; j < ydim; j++) 
        {
            jj = (j + yshift) % ydim;

            iOutputInd = ii * ydim + jj;
            iInputInd = i * ydim + j;
            std::cout << " iOutputInd --> " << iOutputInd << " ;  iInputInd -->" << iInputInd << "\n";


            out[iOutputInd] = in[iInputInd]; // EXCEPTION BEING THROWN HERE
        }
    }
}



int _tmain(int argc, _TCHAR* argv[])
{

    //a = [1 2 3; 4 5 6; 7 8 9];
    mat a, a_out;   // "mat" defined in C++ lib Armadillo
    a << 1 << 2 << 3 << endr
      << 4 << 5 << 6 << endr
      << 7 << 8 << 9  <<endr;
    a.reshape(3,3);
    //a.print();

    a_out = a;

    int xdim = 3; int ydim = 3; int xshift = 1; int yshift = 0;
    circshift(&a_out, &a, xdim, ydim, xshift, yshift);
    a_out.print();

    return 0;
}

编译好。但是,当我尝试运行时,Visual studio会抛出以下错误:

Unhandled exception at 0x3FF00000 in Circshift_Example.exe: 0xC0000005: Access violation (parameters: 0x00000008).

我在visual studio console中遇到另一个错误,抱怨:

error: Mat::init(): requested size is too large

更新:最终解决方案 我发布了我的代码,因为它可能对某些用户有用。

请注意我正在使用&#34; Armadillo&#34;库创建矩阵。人们可以取代Armadillo&#34; mat&#34;用它们自己的矩阵类来表示。

如果您使用此代码,请进行投票。

#include "stdafx.h"
#include "armadillo-3-910-0\include\armadillo"

using namespace arma;


template<class ty>
void circshift(ty& out, const ty& in, int xshift, int yshift)
{
    int iOutputInd, iInputInd, ii, jj;
    int ydim = in.n_cols;
    int xdim = in.n_rows;
    for (int j =0; j < ydim; j++) 
    {
        jj = (j + yshift) % ydim;
        if (jj <0) jj = jj + ydim;
        for (int i = 0; i < xdim; i++) 
        {
            ii = (i + xshift) % xdim;
            if (ii <0) ii = ii + xdim;
            out[jj * xdim + ii] = in[j * xdim + i];
        }
    }
}

int _tmain(int argc, _TCHAR* argv[])
{

    //a = [1 2 3; 4 5 6; 7 8 9];
    mat a, a_out;   
    a << 1 << 2 << 3 << endr
      << 4 << 5 << 6 << endr
      << 7 << 8 << 9  <<endr;
    a.reshape(3,3);

    a_out = a;

    int xshift = 1; int yshift = 0;
    circshift(a_out, a, xshift, yshift);
    a_out.print();  

    xshift = 1; yshift = -1;
    circshift(a_out, a, xshift, yshift);
    a_out.print();


    return 0;
}

1 个答案:

答案 0 :(得分:1)

这里的主要错误是您将mat类型对象的指针传递给circshift()函数(outin参数,但随后将这些参数用作数组至mat。以下行未按您的想法解释

out[iOutputInd] = in[iInputInd];

因为outin不是mat个对象。它们是mat对象的指针,因此编译器会将inout解释为指向mat数组的指针并索引这些数组,复制不存在的mat mat 1}}从[...]到另一个不存在的位置。

解决这个问题的一个简单方法是使用引用而不是指针来传递template<class ty> void circshift(ty& out, const ty& in, int xdim, int ydim, int xshift, int yshift) { ... } 个对象,即:

circshift(a_out, a, xdim, ydim, xshift, yshift);

并使用:

在_tmain中调用它
{{1}}