Board logo

标题: [其他] 矩阵表达式计算器 [打印本页]

作者: slimay    时间: 2021-10-7 21:17     标题: 矩阵表达式计算器

神奇的矩阵表达式运算工具
下载   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. if(eliminateMode == ELIMINATE_INVERSE2)
  6. {
  7. eliminateMode = ELIMINATE_INVERSE;
  8. }
  9. if(eliminateMode == ELIMINATE_GET_DET)
  10. {
  11. eliminateMode = ELIMINATE_TRIANGLE;
  12. }
  13. //获取第一个矩阵列数
  14. int n1 = ( *(mat + 0) );
  15. //获取第一个矩阵行数
  16. int m1 = ( *(mat + 1) );
  17. //低于二阶的矩阵没法阶梯化
  18. if(n1 <2 || m1 < 2)
  19. {
  20. PRINTF_ERROR("The 1-order matrix can't run this.\n", "");
  21. exit(1);
  22. return real_matrix(1.0f / (*(mat + 2)));
  23. }
  24. //用传入矩阵的备份做 高斯若当处理
  25. Matrix* mat1 = (Matrix *)calloc(n1 * m1 + MAT_PRELEN, sizeof(double));
  26. memcpy(mat1, mat, sizeof(double) * (n1 * m1 + MAT_PRELEN) );
  27. //行交换存储器
  28. double exChangeLineTmp[MAX_LEN];
  29. Matrix* matInverse = NULL;
  30. if(eliminateMode == ELIMINATE_INVERSE)
  31. {
  32. //动态分配一个存放逆矩阵的空间
  33. matInverse = (Matrix *)calloc(n1 * m1 + MAT_PRELEN, sizeof(double));
  34. //写入列行数
  35. *(matInverse + 0) =  (double)n1;
  36. *(matInverse + 1) =  (double)m1;
  37. // 先置一同阶单位矩阵
  38. for(int i = 0; i < GET_MIN(n1, m1); i++)
  39. {
  40. *(matInverse + MAT_PRELEN + i + i * n1) = 1.0f;
  41. }
  42. }
  43. //行交换的次数
  44. int exChangeTimes = 0;
  45. //高斯若当消去法置换成上三角型矩阵
  46. int i = 0, j = 0, j_start = 0;
  47. for(i = 0; i < GET_MIN(n1, m1); i++)
  48. {
  49. for(j = j_start; (j < m1) && (i < n1); j++)
  50. {
  51. //找到主元直接中断内循环
  52. if( (*(mat1 + MAT_PRELEN  + i + j_start * n1)) != 0)
  53. {
  54. break;
  55. }
  56. //找到主元为0,则通过行交换使得主元不为0
  57. if( (*(mat1 + MAT_PRELEN  + i + j*n1) != 0) && (j != j_start))
  58. {
  59. memcpy(exChangeLineTmp, mat1 + MAT_PRELEN + j*n1, n1 * sizeof(double));
  60. // i行与j行互换
  61. memcpy(mat1 + MAT_PRELEN + j * n1,    mat1 + MAT_PRELEN + i * n1,            n1 * sizeof(double));
  62. memcpy(mat1 + MAT_PRELEN + i * n1,    exChangeLineTmp,                       n1 * sizeof(double));
  63. // 如果是求逆矩阵模式
  64. if(eliminateMode == ELIMINATE_INVERSE)
  65. {
  66. memcpy(exChangeLineTmp, matInverse + MAT_PRELEN + j*n1, n1 * sizeof(double));
  67. // i行与j行互换
  68. memcpy(matInverse + MAT_PRELEN + j * n1,    matInverse + MAT_PRELEN + i * n1,            n1 * sizeof(double));
  69. memcpy(matInverse + MAT_PRELEN + i * n1,    exChangeLineTmp,                             n1 * sizeof(double));
  70. }
  71. exChangeTimes ++;
  72. break;
  73. }
  74. }
  75. //如果该列主元都为0,直接跳过,处理下一列
  76. if((j == m1) && (*(mat1 + MAT_PRELEN  + i + j_start * n1) == 0))
  77. {
  78. // 这里根据开关选择是否采用阶梯消去法,阶梯消去用于非方阵的m*n型矩阵秩计算
  79. if((eliminateModeBak != ELIMINATE_LADDER))
  80. {
  81. j_start ++;
  82. }
  83. continue;
  84. }
  85. //如果该列主元不为0,则本行除以主元
  86. if( (*(mat1 + MAT_PRELEN  + i + j_start * n1)) != 0)
  87. {
  88. // 这里根据开关选择是否采用主元归一,
  89. if((eliminateMode == ELIMINATE_INVERSE))
  90. {
  91. // 主元归一, 避免误差
  92. double mainPara = (*(mat1 + MAT_PRELEN  + i + j_start*n1));
  93. for(int k = i; k < n1; k++)
  94. {
  95. (*(mat1 + MAT_PRELEN  + k + j_start*n1)) /= mainPara;
  96. // 精度处理
  97. _ZERO_( *(mat1 + MAT_PRELEN  + k + j_start*n1) );
  98. }
  99. if(eliminateMode == ELIMINATE_INVERSE)
  100. {
  101. for(int k = 0; k < n1; k++)
  102. {
  103. (*(matInverse + MAT_PRELEN  + k + j_start*n1)) /= mainPara;
  104. // 精度处理
  105. _ZERO_( *(matInverse + MAT_PRELEN  + k + j_start*n1) );
  106. }
  107. }
  108. }
  109. }
  110. //开始消元
  111. for(j = ( (eliminateMode==ELIMINATE_DIAG) || (eliminateMode==ELIMINATE_INVERSE) )?0 :(j_start + 1); (j < m1) && (i < n1); j++)
  112. {
  113. // 主元不消去自己
  114. if(j == j_start)
  115. {
  116. continue;
  117. }
  118. //计算消去系数
  119. double disLinePara =  - (*(mat1 + MAT_PRELEN  + i + j*n1)) / (*(mat1 + MAT_PRELEN  + i + j_start*n1));
  120. //用主元行消去其他行
  121. for(int k = i; k < n1; k++)
  122. {
  123. (*(mat1 + MAT_PRELEN  + k + j*n1))  +=  disLinePara * (*(mat1 + MAT_PRELEN  + k + j_start*n1));
  124. // 精度处理
  125. _ZERO_(*(mat1 + MAT_PRELEN  + k + j*n1));
  126. }
  127. // 如果是求逆矩阵模式
  128. if(eliminateMode == ELIMINATE_INVERSE)
  129. {
  130. //计算消去系数 (这里沿用左边的消去系数,因为 AE -> EA^(-1),故两边乘以的消去系数一致
  131. double disLineParaInverse = disLinePara ;
  132. //用主元行消去其他行
  133. for(int k = ((eliminateMode==ELIMINATE_DIAG) || (eliminateMode==ELIMINATE_INVERSE) ?0 :i); k < n1; k++)
  134. {
  135. (*(matInverse + MAT_PRELEN  + k + j*n1))  += disLineParaInverse * (*(matInverse + MAT_PRELEN  + k + j_start*n1));
  136. // 精度控制
  137. _ZERO_( *(matInverse + MAT_PRELEN  + k + j*n1) );
  138. }
  139. }
  140. }
  141. //下沉一行
  142. j_start ++;
  143. }
  144. // 如果是det求值模式
  145. if(eliminateModeBak == ELIMINATE_GET_DET)
  146. {
  147. double detValue = 1.0f;
  148. for(int j = 0; j < m1; j++)
  149. {
  150. detValue  *=  (*(mat1 + MAT_PRELEN  + j + j*m1));
  151. }
  152. // 精度控制
  153. _ZERO_(detValue);
  154. //释放备份矩阵内存
  155. free(mat1);
  156. //返回det值 1阶矩阵
  157. return  real_matrix(detValue);
  158. }
  159. //如果是求逆矩阵模式
  160. if(eliminateModeBak == ELIMINATE_INVERSE)
  161. {
  162. //获取首非零行个数
  163. for(int j = 0; j < n1; j++)
  164. {
  165. double mPara = (*(mat1 + MAT_PRELEN  + j + j*n1));
  166. if( mPara == 0.0f )
  167. {
  168. PRINTF_ERROR("The matrix has no inverse mat.\n", "");
  169. exit(1);
  170. }
  171. }
  172. //释放备份矩阵内存
  173. free(mat1);
  174. return  matInverse;
  175. }
  176. //如果是解方程组模式
  177. if(eliminateModeBak == ELIMINATE_INVERSE2)
  178. {
  179. free(matInverse);
  180. return mat1;
  181. }
  182. //返回行交换次数
  183. return mat1;
  184. }
复制代码





欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2