Excel函数使用——求逆矩阵和矩阵的值(Minverse和MDeterm)

来源:互联网 发布:linux安装adobe flash 编辑:程序博客网 时间:2024/05/16 09:14

 

     帮网友解决求逆矩阵的问题。本文的重点是动态数组的使用和SAFEARRAY转换成普通数组的方法(也就是SafeArrayGetElement函数的使用)。

 

// 定义测试数组

int arg2[3][3] = {1, 2, 1,

           3, 4, -1,

           0, 2, 0};

// 计算(这个方法没变)

     VARIANT varArg1;

     SAFEARRAY *psa;

     SAFEARRAYBOUND rgsabound[2];

     rgsabound[0].lLbound = 0;                      // 该维的下界

     rgsabound[0].cElements = 3;                    // 该维的元素个数

     rgsabound[1].lLbound = 0;

     rgsabound[1].cElements = 3;

     long lIndex[2];

     psa = SafeArrayCreate(VT_I4, 2, rgsabound); // 二维

     for (long k = 0; k < (long)3; k++)

     {

         lIndex[0] = k;

         for ( long num = 0; num < (long)3; num++ )

         {

              lIndex[1] = num;

              SafeArrayPutElement (psa, lIndex, &arg2[k][num]); //

 

         }

     }

     varArg1.vt = VT_ARRAY | VT_I4;            // 整型数组

     varArg1.parray = psa;                     // 存储数据

 

     VARIANT varRet = oFun.MInverse( varArg1 );

// 其实结果是正确的,只是开始没有找到提取逆矩阵的方法

// 我通过计算矩阵值的函数来计算逆矩阵,结果与Excel中的吻合

     double varVal = oFun.MDeterm( varRet );   // 0.125,正确

 

// 于是寻找提取逆矩阵的方法

// 定义一个动态的二维数组

VARIANT** arg3;        // 此处必须用VARIANT类型

 

// 根据逆矩阵的维数和大小分配空间

// 先获取逆矩阵的信息

     UINT uDim = SafeArrayGetDim( varRet.parray );

     UINT uEleSize = SafeArrayGetElemsize( varRet.parray );

     long nDim1UBound;

     long nDim1LBound;

     SafeArrayGetUBound( varRet.parray, 1, &nDim1UBound );

     SafeArrayGetLBound( varRet.parray, 1, &nDim1LBound );

     long nDim2UBound;

     long nDim2LBound;

     SafeArrayGetUBound( varRet.parray, 2, &nDim2UBound );

     SafeArrayGetLBound( varRet.parray, 2, &nDim2LBound );

     long nDim1Count = nDim1UBound - nDim1LBound + 1;

     long nDim2Count = nDim2UBound - nDim2LBound + 1;

// 分配空间

     arg3 = new VARIANT *[nDim1UBound];

     for ( int nn = 0; nn < nDim1UBound; nn++ )

     {

         arg3[nn] = new VARIANT[nDim2UBound];

     }   

 

// 提取逆矩阵

     int x = 0;

     int y = 0;

     for ( long nDim1 = nDim1LBound; nDim1 <= nDim1UBound; nDim1++ )

     {

         lIndex[0] = nDim1;

         y = 0;

         for ( long nDim2 = nDim2LBound; nDim2 <= nDim2UBound; nDim2++ )

         {

              lIndex[1] = nDim2;

              SafeArrayGetElement (varRet.parray, lIndex, &arg3[x][y]); //

              y++;

         }

         x++;

     }

 

// 输出测试结果

     for (  i = 0; i < nDim1UBound; i++ )

     {

         for ( int j = 0; j < nDim2UBound; j++ )

         {

              CString strMsg;

              strMsg.Format( _T( "%f" ), arg3[i][j].dblVal );

              AfxMessageBox( strMsg );

         }

     }

 

// 释放内存

     SafeArrayDestroyData( psa );

 

     for ( nn = 0; nn < nDim1UBound; nn++ )

     {

         delete[] arg3[nn];

     }

     delete arg3;

 

// 逆矩阵

0.25 0.25 -0.75

0    0    0.5

0.75 -0.25    -0.25

 

 

原创粉丝点击