找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 11379|回复: 0

[其他] 矩阵表达式计算器

[复制链接]
发表于 2021-10-7 21:17:23 | 显示全部楼层 |阅读模式
神奇的矩阵表达式运算工具
下载   http://cmd1152.ys168.com/  文件区  矩阵表达式计算器.zip
MAT.EXE
摘要:
=============================================================================
矩阵表达式计算器,支持矩阵四则运算,乘方运算计算。
=============================================================================

用法:
-----------------------------------------------------------------------------
mat "[expression1] [expression2] [expression3] [.] ..."
-----------------------------------------------------------------------------

示例:
-----------------------------------------------------------------------------
mat "[A=1,0;1,1] [B=A^(2)] [C=A^(-1)+B] [(A^(-1))-C] [det(A)]"
-----------------------------------------------------------------------------

输入格式:
    {E = en(2)}      <==>   [1   0]
                            [0   1]
    {A = 1,,2;3,8,7} <==>   [1   0   2]
                            [3   8   7]

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
矩阵函数:
    +, -, *, ^, A^(-1), A^(n), cp(A), rot(A), en(A)
    gs(A), diag(A), lad(A), tri(A)
    tr(A), r(A), det(A)
    lf(n): 控制精度
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
常数类
        pi    3.1415926535897932
        e     2.7182818284590452       

通用类
        +     加
        -     减
        *     乘
        /     除
        %     取余数
        ^     次方
        rand  随机数
        round 四舍五入
        int   取整
        ceil  向上舍入
        floor 向下舍入
        sqrt  开方
        lg    常用对数,以10为底
        ln    自然对数
        exp   e的次幂
        deg   度转弧度

三角函数类
        sin、cos、tan   
        arcsin、arccos、arctan

双曲函数类
        sinh、cosh、tanh
        arcsinh、arccosh、arctanh

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

英译:
The matrix calculator, Copyright@2021~2023 Slimay
usage:
    mat "[expression1] [expression2] [expression3] [.] ..."
example:
    mat "[A=1,0;1,1] [B=A^(2)] [C=A^(-1)+B] [(A^(-1))-C] [det(A
    You can use the letters A to O to name the matrix
    {E = en(2)}      <==>   [1   0]
                            [0   1]
    {A = 1,,2;3,8,7} <==>   [1   0   2]
                            [3   8   7]
matrix functions:
    +, -, *, ^, A^(-1), A^(n), cp(A), rot(A), en(A)
    gs(A), diag(A), lad(A), tri(A)
    tr(A), r(A), det(A)
    lf(n): control print precision

mathematical function:
    pi = 3.1415, e = 2.7182, rand, abs, sqrt, lg, ln, exp
    sin, cos, tan, arcsin, arccos, arctan
version 1.0.5
COPYRIGHT@2021~2023 BY SLIMAY, VERSION 1.0
MAT.EXE


核心代码
  1. //高斯若当主函数
  2. Matrix* Gauss_Jordan_Elimination(Matrix* mat, int eliminateMode)
  3. {
  4.         int eliminateModeBak =  eliminateMode;
  5.        
  6.         if(eliminateMode == ELIMINATE_INVERSE2)
  7.         {
  8.                 eliminateMode = ELIMINATE_INVERSE;
  9.         }

  10.         if(eliminateMode == ELIMINATE_GET_DET)
  11.         {
  12.                 eliminateMode = ELIMINATE_TRIANGLE;
  13.         }
  14.        
  15.         //获取第一个矩阵列数
  16.         int n1 = ( *(mat + 0) );
  17.         //获取第一个矩阵行数
  18.         int m1 = ( *(mat + 1) );


  19.         //低于二阶的矩阵没法阶梯化
  20.         if(n1 <2 || m1 < 2)
  21.         {
  22.                 PRINTF_ERROR("The 1-order matrix can't run this.\n", "");
  23.                 exit(1);
  24.                 return real_matrix(1.0f / (*(mat + 2)));
  25.         }

  26.         //用传入矩阵的备份做 高斯若当处理
  27.         Matrix* mat1 = (Matrix *)calloc(n1 * m1 + MAT_PRELEN, sizeof(double));
  28.         memcpy(mat1, mat, sizeof(double) * (n1 * m1 + MAT_PRELEN) );

  29.         //行交换存储器
  30.         double exChangeLineTmp[MAX_LEN];
  31.        
  32.         Matrix* matInverse = NULL;
  33.        
  34.         if(eliminateMode == ELIMINATE_INVERSE)
  35.         {
  36.                 //动态分配一个存放逆矩阵的空间
  37.                 matInverse = (Matrix *)calloc(n1 * m1 + MAT_PRELEN, sizeof(double));
  38.                 //写入列行数
  39.                 *(matInverse + 0) =  (double)n1;
  40.                 *(matInverse + 1) =  (double)m1;
  41.                 // 先置一同阶单位矩阵
  42.                 for(int i = 0; i < GET_MIN(n1, m1); i++)
  43.                 {
  44.                         *(matInverse + MAT_PRELEN + i + i * n1) = 1.0f;
  45.                 }
  46.         }
  47.        
  48.         //行交换的次数
  49.         int exChangeTimes = 0;
  50.         //高斯若当消去法置换成上三角型矩阵
  51.         int i = 0, j = 0, j_start = 0;
  52.         for(i = 0; i < GET_MIN(n1, m1); i++)
  53.         {       
  54.                 for(j = j_start; (j < m1) && (i < n1); j++)
  55.                 {
  56.                         //找到主元直接中断内循环
  57.                         if( (*(mat1 + MAT_PRELEN  + i + j_start * n1)) != 0)
  58.                         {
  59.                                 break;
  60.                         }
  61.                         //找到主元为0,则通过行交换使得主元不为0
  62.                         if( (*(mat1 + MAT_PRELEN  + i + j*n1) != 0) && (j != j_start))
  63.                         {
  64.                                
  65.                                 memcpy(exChangeLineTmp, mat1 + MAT_PRELEN + j*n1, n1 * sizeof(double));                       
  66.                                 // i行与j行互换
  67.                                 memcpy(mat1 + MAT_PRELEN + j * n1,    mat1 + MAT_PRELEN + i * n1,            n1 * sizeof(double));
  68.                                 memcpy(mat1 + MAT_PRELEN + i * n1,    exChangeLineTmp,                       n1 * sizeof(double));
  69.                                
  70.                                 // 如果是求逆矩阵模式
  71.                                 if(eliminateMode == ELIMINATE_INVERSE)
  72.                                 {
  73.                                         memcpy(exChangeLineTmp, matInverse + MAT_PRELEN + j*n1, n1 * sizeof(double));                       
  74.                                         // i行与j行互换
  75.                                         memcpy(matInverse + MAT_PRELEN + j * n1,    matInverse + MAT_PRELEN + i * n1,            n1 * sizeof(double));
  76.                                         memcpy(matInverse + MAT_PRELEN + i * n1,    exChangeLineTmp,                             n1 * sizeof(double));
  77.                                 }
  78.                                                
  79.                                 exChangeTimes ++;
  80.                                 break;
  81.                         }
  82.                 }

  83.                 //如果该列主元都为0,直接跳过,处理下一列
  84.                 if((j == m1) && (*(mat1 + MAT_PRELEN  + i + j_start * n1) == 0))
  85.                 {
  86.                         // 这里根据开关选择是否采用阶梯消去法,阶梯消去用于非方阵的m*n型矩阵秩计算
  87.                         if((eliminateModeBak != ELIMINATE_LADDER))
  88.                         {
  89.                                 j_start ++;
  90.                         }
  91.                         continue;
  92.                 }

  93.                 //如果该列主元不为0,则本行除以主元
  94.                 if( (*(mat1 + MAT_PRELEN  + i + j_start * n1)) != 0)
  95.                 {
  96.                         // 这里根据开关选择是否采用主元归一,
  97.                         if((eliminateMode == ELIMINATE_INVERSE))
  98.                         {
  99.                                 // 主元归一, 避免误差
  100.                                 double mainPara = (*(mat1 + MAT_PRELEN  + i + j_start*n1));
  101.                                 for(int k = i; k < n1; k++)
  102.                                 {
  103.                                         (*(mat1 + MAT_PRELEN  + k + j_start*n1)) /= mainPara;
  104.                                        
  105.                                         // 精度处理
  106.                                         _ZERO_( *(mat1 + MAT_PRELEN  + k + j_start*n1) );
  107.                                 }
  108.                                
  109.                                 if(eliminateMode == ELIMINATE_INVERSE)
  110.                                 {
  111.                                         for(int k = 0; k < n1; k++)
  112.                                         {
  113.                                                 (*(matInverse + MAT_PRELEN  + k + j_start*n1)) /= mainPara;

  114.                                                 // 精度处理
  115.                                                 _ZERO_( *(matInverse + MAT_PRELEN  + k + j_start*n1) );       
  116.                                         }
  117.                                 }
  118.                         }
  119.                 }

  120.                 //开始消元
  121.                 for(j = ( (eliminateMode==ELIMINATE_DIAG) || (eliminateMode==ELIMINATE_INVERSE) )?0 :(j_start + 1); (j < m1) && (i < n1); j++)
  122.                 {
  123.                         // 主元不消去自己
  124.                         if(j == j_start)
  125.                         {
  126.                                 continue;
  127.                         }
  128.                        
  129.                         //计算消去系数
  130.                         double disLinePara =  - (*(mat1 + MAT_PRELEN  + i + j*n1)) / (*(mat1 + MAT_PRELEN  + i + j_start*n1));
  131.                                
  132.                         //用主元行消去其他行
  133.                         for(int k = i; k < n1; k++)
  134.                         {
  135.                                 (*(mat1 + MAT_PRELEN  + k + j*n1))  +=  disLinePara * (*(mat1 + MAT_PRELEN  + k + j_start*n1));
  136.                                        
  137.                                 // 精度处理
  138.                                 _ZERO_(*(mat1 + MAT_PRELEN  + k + j*n1));
  139.                         }
  140.                        
  141.                         // 如果是求逆矩阵模式
  142.                         if(eliminateMode == ELIMINATE_INVERSE)
  143.                         {
  144.                                 //计算消去系数 (这里沿用左边的消去系数,因为 AE -> EA^(-1),故两边乘以的消去系数一致
  145.                                 double disLineParaInverse = disLinePara ;
  146.                                        
  147.                                 //用主元行消去其他行
  148.                                 for(int k = ((eliminateMode==ELIMINATE_DIAG) || (eliminateMode==ELIMINATE_INVERSE) ?0 :i); k < n1; k++)
  149.                                 {
  150.                                         (*(matInverse + MAT_PRELEN  + k + j*n1))  += disLineParaInverse * (*(matInverse + MAT_PRELEN  + k + j_start*n1));
  151.                                         // 精度控制
  152.                                         _ZERO_( *(matInverse + MAT_PRELEN  + k + j*n1) );
  153.                                 }
  154.                         }
  155.                 }

  156.                 //下沉一行
  157.                 j_start ++;       
  158.         }
  159.        
  160.         // 如果是det求值模式
  161.         if(eliminateModeBak == ELIMINATE_GET_DET)
  162.         {       
  163.                 double detValue = 1.0f;       
  164.                 for(int j = 0; j < m1; j++)
  165.                 {
  166.                          detValue  *=  (*(mat1 + MAT_PRELEN  + j + j*m1));
  167.                 }
  168.                
  169.                 // 精度控制
  170.                 _ZERO_(detValue);
  171.                                
  172.                 //释放备份矩阵内存
  173.                 free(mat1);
  174.                        
  175.                 //返回det值 1阶矩阵
  176.                 return  real_matrix(detValue);
  177.         }
  178.        
  179.         //如果是求逆矩阵模式
  180.         if(eliminateModeBak == ELIMINATE_INVERSE)
  181.         {
  182.                 //获取首非零行个数
  183.                 for(int j = 0; j < n1; j++)
  184.                 {
  185.                         double mPara = (*(mat1 + MAT_PRELEN  + j + j*n1));
  186.                         if( mPara == 0.0f )
  187.                         {
  188.                                 PRINTF_ERROR("The matrix has no inverse mat.\n", "");
  189.                                 exit(1);
  190.                         }
  191.                 }
  192.                
  193.                 //释放备份矩阵内存
  194.                 free(mat1);       
  195.                 return  matInverse;
  196.         }

  197.         //如果是解方程组模式
  198.         if(eliminateModeBak == ELIMINATE_INVERSE2)
  199.         {
  200.                 free(matInverse);
  201.                 return mat1;
  202.         }

  203.         //返回行交换次数
  204.         return mat1;
  205. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 02:50 , Processed in 0.009066 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表