【问题标题】:set member function of the schmatrix class in cvm library is throwing an exception but why?cvm 库中 schmatrix 类的 set 成员函数抛出异常,但为什么呢?
【发布时间】:2017-01-18 02:28:20
【问题描述】:

我通过在mx_minimum_power.cpp 中添加以下代码创建了一个 mex 函数

#include <math.h>
#include <complex>
#include "mex.h"
#include "matrix.h"
#include "cvm.h"
#include "blas.h"
#include "cfun.h"

using std::complex;
using namespace cvm;

/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    const int arraysize = 62172;
    const int matrixDimention = 3;
    float *inMatrixA11 = (float *)mxGetPr(prhs[0]);
    complex<float> *inMatrixA12 = (complex<float> *)mxGetPr(prhs[1]);
    complex<float> *inMatrixA13 = (complex<float> *)mxGetPr(prhs[2]);
    float *inMatrixA22 = (float *)mxGetPr(prhs[3]);
    complex<float> *inMatrixA23 = (complex<float> *)mxGetPr(prhs[4]);
    float *inMatrixA33 = (float *)mxGetPr(prhs[5]);
    basic_schmatrix< float, complex<float> > A(matrixDimention);
    int i = 0;
    for (i = 0; i < arraysize; i++)
    {
        A.set(1, 1, inMatrixA11[i]);
        A.set(1, 2, inMatrixA12[i]);
        A.set(1, 3, inMatrixA13[i]);
        A.set(2, 2, inMatrixA22[i]);
        A.set(2, 3, inMatrixA23[i]);
        A.set(3, 3, inMatrixA33[i]);
    }
}  

然后我通过在 matlab 命令行中输入以下代码创建了mx_minimum_power.mexw64

mex -g mx_minimum_power.cpp cvm_em64t_debug.lib  

但似乎set member function of basic_schmatrix class 在第 27 行 A.set(1, 1, inMatrixA11[i]); 抛出了一个 cvmexception

我真的不明白这个例外的原因,因为我在CVM0 based indexing 中使用了[1,4) 范围内的索引1,1
并且还考虑到在运行第 27 行 A.set(1, 1, inMatrixA11[i]); 之前,我们有以下 A11[0],A12[0],A13[0],A22[0],A23[0],A33[0] 的值:

正如预期的那样。

并为hermitian matrix A分配了以下内存:

【问题讨论】:

    标签: c++ visual-studio exception visual-c++ visual-studio-2013


    【解决方案1】:

    问题出现是因为我们在cvm.h文件的第48到53行有如下代码:

    // 5.7 0-based indexing
    #if defined (CVM_ZERO_BASED)
    #   define CVM0 TINT_ZERO //!< Index base, 1  by default or 0 when \c CVM_ZERO_BASED is defined
    #else
    #   define CVM0 TINT_ONE  //!< Index base, 1  by default or 0 when \c CVM_ZERO_BASED is defined
    #endif  
    

    默认情况下会生成CVM0 = 1。所以如果我们在指定行按下Step Into(F11)按钮两次,我们将进入文件cvm.h的第34883行:

    basic_schmatrix& set(tint nRow, tint nCol, TC c) throw(cvmexception)
    {
        this->_set_at(nRow - CVM0, nCol - CVM0, c);
        return *this;
    }  
    

    this-&gt;_set_at(nRow - CVM0, nCol - CVM0, c); 行按Step Into(F11),您将转到函数_set_at 的定义:

    // sets both elements to keep matrix hermitian, checks ranges
    // zero based
    void _set_at(tint nRow, tint nCol, TC val) throw(cvmexception)
    {
        _check_lt_ge(CVM_OUTOFRANGE_LTGE1, nRow, CVM0, this->msize() + CVM0);
        _check_lt_ge(CVM_OUTOFRANGE_LTGE2, nCol, CVM0, this->nsize() + CVM0);
        if (nRow == nCol && _abs(val.imag()) > basic_cvmMachMin<TR>()) { // only reals on main diagonal
            throw cvmexception(CVM_BREAKS_HERMITIANITY, "real number");
        }
        this->get()[this->ld() * nCol + nRow] = val;
        if (nRow != nCol) {
            this->get()[this->ld() * nRow + nCol] = _conjugate(val);
        }
    }
    

    按下Step Over(F10)按钮,你会得到结果:

    所以为了得到nRow=1nCol=1 而不是nRow=0nCol=0,它们超出了[1,4) 的范围,您应该将该行代码编写为:

    A.set(2, 2, inMatrixA11[i]);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-09
      • 1970-01-01
      • 2011-12-12
      • 2018-01-13
      • 1970-01-01
      • 2014-08-12
      相关资源
      最近更新 更多