|
| 1 | +/* |
| 2 | +\ \ __ ___ __ _ __ __ __ |
| 3 | + \ \ / |/ /__ _/ /_____(_)_ __ / // /_ __/ / |
| 4 | + / / / /|_/ / _ `/ __/ __/ /\ \ // _ / // / _ \ |
| 5 | +/ / /_/ /_/\_,_/\__/_/ /_//_\_\/_//_/\_,_/_.__/ |
| 6 | +* [INFORMATION] |
| 7 | + MATRIX_HUB |
| 8 | + AUTHOR: Xiping.Yu |
| 9 | + E-MAIL: Amoiensis@outlook.com |
| 10 | + GITHUB: https://github.com/Amoiensis/Matrix_hub |
| 11 | + DATE: 2020.02.12-2022.08.21 |
| 12 | + VERSION: 1.5.2 |
| 13 | + CASE: Matrix Operation (C) |
| 14 | + DETAILS: The demo-code for Matrix_Hub. |
| 15 | + LICENSE: Apache-2.0 |
| 16 | +*/ |
| 17 | + |
| 18 | +#include <stdio.h> |
| 19 | +#include <stdlib.h> |
| 20 | +#include "matrix.h" |
| 21 | +# include "./solver_plugin/plugin_LP_Sover.h" |
| 22 | + |
| 23 | + |
| 24 | +int main(int argc, char *argv[]) { |
| 25 | + system("color 0F"); |
| 26 | + |
| 27 | +/* [Setting Matrix]*/ |
| 28 | + // Mat_1 |
| 29 | + MATRIX_TYPE _mat_1[3][5] = {2, 2, 2, 1, 1, |
| 30 | + 4, 1, 1, 2, 1, |
| 31 | + 1, 5, 1, 1, 2}; |
| 32 | + int row = sizeof(_mat_1) / sizeof(_mat_1[0]); |
| 33 | + int column = sizeof(_mat_1[0]) / sizeof(_mat_1[0][0]); |
| 34 | + Matrix *mat_1 = Matrix_gen(row, column, _mat_1); |
| 35 | + M_print(mat_1); |
| 36 | + // Mat_2 |
| 37 | + MATRIX_TYPE _mat_2[5][3] = {1, 2, 3, 4, 5, 6, 7, 8, 7, 10, 11, 12, 11, 14, 15}; |
| 38 | + // MATRIX_TYPE _mat_2[5][2] = { 1,2,3,4,5,6,7,8,9,10}; |
| 39 | + row = sizeof(_mat_2) / sizeof(_mat_2[0]); |
| 40 | + column = sizeof(_mat_2[0]) / sizeof(_mat_2[0][0]); |
| 41 | + Matrix *mat_2 = Matrix_gen(row, column, _mat_2); |
| 42 | + // M_print(mat_2); |
| 43 | + // Mat_A |
| 44 | + MATRIX_TYPE _mat_A[5][5] = {1, 0, 7, 0, 9, 0, 7, 0, 9, 0, 0, 0, -5, 0, 4, 2, 0, 0, 2, 0, 0, 3, 8, 0, 1}; |
| 45 | + row = sizeof(_mat_A) / sizeof(_mat_A[0]); |
| 46 | + column = sizeof(_mat_A[0]) / sizeof(_mat_A[0][0]); |
| 47 | + Matrix *mat_A = Matrix_gen(row, column, _mat_A); |
| 48 | + // M_print(mat_A); |
| 49 | + // A_10 |
| 50 | + MATRIX_TYPE _mat_A10[10][10] = {0.221746734017240, 0.928854139478045, 0.488897743920167, 0.0987122786555743, |
| 51 | + 0.715037078400694, 0.904722238067363, 0.489901388512224, 0.521649842464284, |
| 52 | + 0.800330575352402, 0.0604711791698936, 0.117417650855806, 0.730330862855453, |
| 53 | + 0.624060088173690, 0.261871183870716, 0.903720560556316, 0.609866648422558, |
| 54 | + 0.167927145682257, 0.0967300257808670, 0.453797708726920, 0.399257770613576, |
| 55 | + 0.296675873218327, 0.488608973803579, 0.679135540865748, 0.335356839962797, |
| 56 | + 0.890922504330789, 0.617666389588455, 0.978680649641159, 0.818148553859625, |
| 57 | + 0.432391503783462, 0.526875830508296, 0.318778301925882, 0.578525061023439, |
| 58 | + 0.395515215668593, 0.679727951377338, 0.334163052737496, 0.859442305646212, |
| 59 | + 0.712694471678914, 0.817547092079286, 0.825313795402046, 0.416799467930787, |
| 60 | + 0.424166759713807, 0.237283579771521, 0.367436648544477, 0.136553137355370, |
| 61 | + 0.698745832334795, 0.805489424529686, 0.500471624154843, 0.722439592366842, |
| 62 | + 0.0834698148589140, 0.656859890973707, 0.507858284661118, 0.458848828179931, |
| 63 | + 0.987982003161633, 0.721227498581740, 0.197809826685929, 0.576721515614685, |
| 64 | + 0.471088374541939, 0.149865442477967, 0.133171007607162, 0.627973359190104, |
| 65 | + 0.0855157970900440, 0.963088539286913, 0.0377388662395521, 0.106761861607241, |
| 66 | + 0.0305409463046367, 0.182922469414914, 0.0596188675796392, 0.659605252908307, |
| 67 | + 0.173388613119006, 0.291984079961715, 0.262482234698333, 0.546805718738968, |
| 68 | + 0.885168008202475, 0.653757348668560, 0.744074260367462, 0.239932010568717, |
| 69 | + 0.681971904149063, 0.518594942510538, 0.390937802323736, 0.431651170248720, |
| 70 | + 0.801014622769739, 0.521135830804002, 0.913286827639239, 0.494173936639270, |
| 71 | + 0.500022435590201, 0.886511933076101, 0.0424311375007417, 0.972974554763863, |
| 72 | + 0.831379742839070, 0.0154871256360190, 0.0292202775621463, 0.231594386708524, |
| 73 | + 0.796183873585212, 0.779051723231275, 0.479922141146060, 0.0286741524641061, |
| 74 | + 0.0714454646006424, 0.648991492712356, 0.803364391602440, 0.984063724379154}; |
| 75 | + row = sizeof(_mat_A10) / sizeof(_mat_A10[0]); |
| 76 | + column = sizeof(_mat_A10[0]) / sizeof(_mat_A10[0][0]); |
| 77 | + Matrix *mat_A10 = Matrix_gen(row, column, _mat_A10); |
| 78 | + // M_print(mat_A10); |
| 79 | + // Mat_21 |
| 80 | + MATRIX_TYPE _mat_21[3][3] = {0, 2, 3, 2, 1, 2, 4, 1, 3}; |
| 81 | + row = sizeof(_mat_21) / sizeof(_mat_21[0]); |
| 82 | + column = sizeof(_mat_21[0]) / sizeof(_mat_21[0][0]); |
| 83 | + Matrix *mat_21 = Matrix_gen(row, column, _mat_21); |
| 84 | + // M_print(mat_21); |
| 85 | + // Mat_21b |
| 86 | + MATRIX_TYPE _mat_21b[3][3] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; |
| 87 | + row = sizeof(_mat_21b) / sizeof(_mat_21b[0]); |
| 88 | + column = sizeof(_mat_21b[0]) / sizeof(_mat_21b[0][0]); |
| 89 | + Matrix *mat_21b = Matrix_gen(row, column, _mat_21b); |
| 90 | + // M_print(mat_21b); |
| 91 | + // Mat_b |
| 92 | + MATRIX_TYPE _mat_b[5][1] = {1, 2, 7, 2, 4}; |
| 93 | + row = sizeof(_mat_b) / sizeof(_mat_b[0]); |
| 94 | + column = sizeof(_mat_b[0]) / sizeof(_mat_b[0][0]); |
| 95 | + Matrix *mat_b = Matrix_gen(row, column, _mat_b); |
| 96 | + // M_print(mat_b); |
| 97 | + // B_10 |
| 98 | + MATRIX_TYPE _mat_b10[10][1] = {0.167168409914656, 0.106216344928664, 0.372409740055537, 0.198118402542975, |
| 99 | + 0.489687638016024, 0.339493413390758, 0.951630464777727, 0.920332039836564, |
| 100 | + 0.0526769976807926, 0.737858095516997}; |
| 101 | + row = sizeof(_mat_b10) / sizeof(_mat_b10[0]); |
| 102 | + column = sizeof(_mat_b10[0]) / sizeof(_mat_b10[0][0]); |
| 103 | + Matrix *mat_b10 = Matrix_gen(row, column, _mat_b10); |
| 104 | + // M_print(mat_b10); |
| 105 | + // Mat_eigen_test |
| 106 | + MATRIX_TYPE _mat_eigen_test[3][3] = { |
| 107 | + 3.000,2.000,3.000, |
| 108 | + 4.000,5.000,6.000, |
| 109 | + 2.000,8.000,9.000, |
| 110 | + }; |
| 111 | + row = sizeof(_mat_eigen_test) / sizeof(_mat_eigen_test[0]); |
| 112 | + column = sizeof(_mat_eigen_test[0]) / sizeof(_mat_eigen_test[0][0]); |
| 113 | + Matrix *mat_eigen_test = Matrix_gen(row, column, _mat_eigen_test); |
| 114 | + // M_print(mat_eigen_test); |
| 115 | + // Mat_test |
| 116 | + MATRIX_TYPE _mat_inv_test[5][5] = { |
| 117 | + 1900.687134, 1774.058105, 1474.243774, 1084.511719, 680.7639771, |
| 118 | + 1506.677734, 1474.243774, 1348.486084, 1052.940186, 679.0471191, |
| 119 | + 1087.057983, 1084.511719, 1052.940186, 931.4074707, 651.5393677, |
| 120 | + 680.8083496, 680.7639771, 679.0471191, 651.5393677, 545.0874634, |
| 121 | + 319.0212097, 319.1206055, 319.8133545, 321.7086487, 307.6086426 |
| 122 | + }; |
| 123 | + row = sizeof(_mat_inv_test) / sizeof(_mat_inv_test[0]); |
| 124 | + column = sizeof(_mat_inv_test[0]) / sizeof(_mat_inv_test[0][0]); |
| 125 | + Matrix *mat_inv_test = Matrix_gen(row, column, _mat_inv_test); |
| 126 | + // M_print(mat_inv_test); |
| 127 | + |
| 128 | + MATRIX_TYPE _mat_A_lp[4][7] = { |
| 129 | + 1,0,0,0,1,1,1, |
| 130 | + 0,1,0,0,1,0,0, |
| 131 | + 0,0,1,0,0,0,1, |
| 132 | + 0,0,0,1,0,3,1 |
| 133 | + }; |
| 134 | + MATRIX_TYPE _mat_B_lp[4][1] = |
| 135 | + {4,2,3,6}; |
| 136 | + MATRIX_TYPE _mat_C_lp [1][7] = |
| 137 | + {0,0,0,0,1,14,6,}; |
| 138 | + row = sizeof(_mat_A_lp) / sizeof(_mat_A_lp[0]); |
| 139 | + column = sizeof(_mat_A_lp[0]) / sizeof(_mat_A_lp[0][0]); |
| 140 | + Matrix* mat_A_lp = Matrix_gen(row,column,_mat_A_lp); |
| 141 | + /*M B*/ |
| 142 | + row = sizeof(_mat_B_lp) / sizeof(_mat_B_lp[0]); |
| 143 | + column = sizeof(_mat_B_lp[0]) / sizeof(_mat_B_lp[0][0]); |
| 144 | + Matrix* mat_B_lp = Matrix_gen(row,column,_mat_B_lp); |
| 145 | + /*M C*/ |
| 146 | + row = sizeof(_mat_C_lp) / sizeof(_mat_C_lp[0]); |
| 147 | + column = sizeof(_mat_C_lp[0]) / sizeof(_mat_C_lp[0][0]); |
| 148 | + Matrix* mat_C_lp = Matrix_gen(row,column,_mat_C_lp); |
| 149 | + |
| 150 | +/* [Matrix Operation]*/ |
| 151 | + // 乘法 |
| 152 | + printf("->> Function: M_mul\n"); |
| 153 | + Matrix *mat_3 = M_mul(mat_2, mat_1); |
| 154 | + M_print(mat_3); |
| 155 | + // 加减法 |
| 156 | + printf("->> Function: M_add_sub\n"); |
| 157 | + Matrix *mat_diff = M_add_sub(1, mat_21, 1, mat_21b); |
| 158 | + M_print(mat_diff); |
| 159 | + // 初等变换 |
| 160 | + printf("->> Function: M_E_trans\n"); |
| 161 | + Etrans_struct _Etrans_; |
| 162 | + _Etrans_.minuend_line = 2; |
| 163 | + _Etrans_.subtractor_line = 1; |
| 164 | + _Etrans_.scale = 2; |
| 165 | + _Etrans_.next_E_trans = NULL; |
| 166 | + _Etrans_.forward_E_trans = NULL; |
| 167 | + M_E_trans(mat_2, &_Etrans_, _ROW_); |
| 168 | + M_print(mat_2); |
| 169 | + // 单位矩阵 |
| 170 | + printf("->> Function: M_I\n"); |
| 171 | + M_print(M_I(5)); |
| 172 | + // 初等变换to矩阵 |
| 173 | + printf("->> Function: Etrans_2_Matrix\n"); |
| 174 | + Matrix *mat_4 = Etrans_2_Matrix(&_Etrans_, 5, _ROW_); |
| 175 | + M_print(mat_4); |
| 176 | + // 上三角变换 |
| 177 | + printf("->> Function: M_Uptri_\n"); |
| 178 | + Uptri_struct *_Uptri_ = M_Uptri_(mat_21); |
| 179 | + M_print(_Uptri_->trans_matrix); |
| 180 | + M_print(_Uptri_->Uptri_matrix); |
| 181 | + // 下三角变换 |
| 182 | + printf("->> Function: M_Lowtri_\n"); |
| 183 | + Lowtri_struct *_Lowtri_ = M_Lowtri_(mat_21); |
| 184 | + M_print(_Lowtri_->Lowtri_matrix); |
| 185 | + M_print(_Lowtri_->trans_matrix); |
| 186 | + // 对角化 |
| 187 | + printf("->> Function: M_Diatri_\n"); |
| 188 | + Dia_struct *_Dia_ = M_Diatri_(mat_21); |
| 189 | + M_print(_Dia_->trans_leftmatrix); |
| 190 | + M_print(_Dia_->Diatri_matrix); |
| 191 | + M_print(_Dia_->trans_rightmatrix); |
| 192 | + // 矩阵求逆 |
| 193 | + printf("->> Function: M_Inverse\n"); |
| 194 | + Matrix *_mat_inv = M_Inverse(mat_21); |
| 195 | + M_print(_mat_inv); |
| 196 | + // 行列交换 |
| 197 | + M_Swap(_mat_inv, 1, 2, _ROW_); |
| 198 | + M_print(_mat_inv); |
| 199 | + // 切割部分 |
| 200 | + printf("->> Function: M_Cut\n"); |
| 201 | + Matrix *_mat_cut = M_Cut(_mat_inv, _END_, _END_, 2, 3); |
| 202 | + M_print(_mat_cut); |
| 203 | + // 转置 |
| 204 | + printf("->> Function: M_T\n"); |
| 205 | + Matrix *_mat_T = M_T(_mat_inv); |
| 206 | + M_print(_mat_T); |
| 207 | + // 迹 |
| 208 | + MATRIX_TYPE _tr_mat = M_tr(_mat_inv); |
| 209 | + printf("Trace(Matrix_%x) = %.4lf\n", _mat_inv, _tr_mat); |
| 210 | + // 行列式 |
| 211 | + MATRIX_TYPE _det_mat = M_det(_mat_inv); |
| 212 | + printf("Det(Matrix_%x) = %.4lf\n", mat_21, _det_mat); |
| 213 | + // 填充 |
| 214 | + printf("->> Function: M_full\n"); |
| 215 | + Matrix *mat_full = M_full(mat_2, 1, 1, 1, 1, 0); |
| 216 | + M_print(mat_full); |
| 217 | + M_print(mat_2); |
| 218 | + // 范数 |
| 219 | + printf("NORM_L1(mat_%x) = %lf\n",mat_b, M_norm(mat_b, 1)); |
| 220 | + printf("NORM_L2(mat_%x) = %lf\n",mat_b, M_norm(mat_b, 2)); |
| 221 | + // 秩 |
| 222 | + printf("Rank(mat_%x) = %d\n", mat_A10, M_rank(mat_A10)); |
| 223 | + printf("Rank(mat_%x) = %d\n", mat_full, M_rank(mat_full)); |
| 224 | + // Hilbert 希尔伯特矩阵 |
| 225 | + printf("->> Gen Hilbert-Matrix\n"); |
| 226 | + M_print(Hilbert(5)); |
| 227 | + // 条件数计算 |
| 228 | + printf("->> Condition_Value = %lf\n", M_cond(Hilbert(5),1)); |
| 229 | + // 矩阵householder变换 |
| 230 | + printf("->> Function: M_householder.\n"); |
| 231 | + Matrix * M_H = M_householder(Hilbert(5)); |
| 232 | + M_print(M_H); |
| 233 | + // 矩阵特征值 + 特征向量 |
| 234 | + printf("->> Function: M_eigen.\n"); |
| 235 | + Matrix *target = mat_eigen_test; |
| 236 | + M_print(target); |
| 237 | + Matrix ** M_eigen_val_vec = M_eigen(target); |
| 238 | + enum{val=0, vec=1}; |
| 239 | + M_print(M_eigen_val_vec[val]); |
| 240 | + M_print(M_eigen_val_vec[vec]); |
| 241 | + // 矩阵QR分解 |
| 242 | + printf("->> Function: M_QR.\n"); |
| 243 | + Matrix ** M_Q_R = M_QR(Hilbert(5)); |
| 244 | + enum{q=0, r=1}; |
| 245 | + M_print(M_Q_R[q]); |
| 246 | + M_print(M_Q_R[r]); |
| 247 | + // 矩阵 SVD 分解. |
| 248 | + printf("->> Function: M_SVD.\n"); |
| 249 | + Matrix ** mat_list_SVD = M_SVD(mat_1); |
| 250 | + M_print(mat_1); |
| 251 | + enum{U=0, Dia=1, V=2}; |
| 252 | + M_print(mat_list_SVD[U]); |
| 253 | + M_print(mat_list_SVD[Dia]); |
| 254 | + M_print(mat_list_SVD[V]); |
| 255 | + // 矩阵求伪逆 |
| 256 | + printf("->> Function: pseudo-inverse (pinv).\n"); |
| 257 | + M_print(mat_1); |
| 258 | + Matrix * mat_pinv = M_pinv(mat_1, _SVD_); |
| 259 | + M_print(mat_pinv); |
| 260 | + |
| 261 | +/* [Application]*/ |
| 262 | + /* [CASE 1: LP] |
| 263 | + | min CX |
| 264 | + |s.t. AX=b,X>=0 |
| 265 | + LP: linear programming, 求解线性规划. |
| 266 | + [Note.] 需要在main文件引入 "plugin_LP_Sover.h" |
| 267 | + # include "./solver_plugin/plugin_LP_Sover.h" |
| 268 | + */ |
| 269 | + M_LP_struct* LP_result = NULL; |
| 270 | + // [LP-Case 1] |
| 271 | + enum LP_method{_Simplex=1,}; |
| 272 | + printf("*** LP-SOLVER START ***\n"); |
| 273 | + LP_result = LP_Solver(mat_A_lp, mat_B_lp,mat_C_lp, _Simplex); // 使用单纯形法解线性规划. |
| 274 | + printf("*** LP-SOLVER END ***\n"); |
| 275 | + if (LP_result != NULL){ |
| 276 | + printf("[COST]\n"); // mat_C_lp, C矩阵, 成本矩阵. |
| 277 | + M_print(LP_result->_matrix_c); |
| 278 | + printf("[BASE]\n"); // 最优解的基构成 |
| 279 | + M_print(LP_result->_matrix_base); |
| 280 | + printf("[VALUES]\n"); // 最优值 |
| 281 | + M_print(M_T(LP_result->_matrix_b)); |
| 282 | + printf("[MAT_A]\n"); // 最后的变换系数矩阵. |
| 283 | + M_print(LP_result->_matrix_A); |
| 284 | + printf("[DELTA]\n"); // 各基的delta. |
| 285 | + M_print(LP_result->_matrix_delta); |
| 286 | + printf(">> OPT-VALUES: %lf\n", LP_result->values_opt); // 求解状态. |
| 287 | + printf(">> iter-num: %d\n", LP_result->iter_num); |
| 288 | + printf(">> [Note.] Please Check is Feasible or Not.\n"); // 求解迭代次数. |
| 289 | + LP_free(LP_result); |
| 290 | + }else{ |
| 291 | + system("pause"); |
| 292 | + printf("[NO FEASIBLE.] SEARCH ALL BRANCHES.\n"); |
| 293 | + } |
| 294 | + |
| 295 | + // [ CASE 2: linear equations solver]linear equations, |
| 296 | + // 解线性方程. e.g. mat_A*x = mat_b |
| 297 | + printf("# Solver:mat_A*x = mat_b\n"); |
| 298 | + Matrix *_mat_result = M_mul(M_Inverse(mat_A10), mat_b10); |
| 299 | + M_print(_mat_result); |
| 300 | + |
| 301 | + // [ CASE OTHERS] |
| 302 | + // 解线性方程. e.g. mat_A*x = mat_b |
| 303 | + // 测试 Hilbert 希尔伯特矩阵(病态矩阵) |
| 304 | + // Hilbert(n)*x = One(n,1) |
| 305 | + int order = 10; |
| 306 | + printf("# Solver:Hilbert(%d)*x = One(%d,1)\n", order, order); |
| 307 | + M_print(M_mul(M_Inverse(Hilbert(order)), M_Ones(order,1))); |
| 308 | + // 测试希尔伯特矩阵的秩 |
| 309 | + printf("->>Rank(Hilbert(%d)) = %d\n",order, M_rank(Hilbert(order))); |
| 310 | + // 条件数计算 |
| 311 | + printf("->>Condition Value = %lf\n", M_cond(mat_inv_test,1)); |
| 312 | + M_print(M_Inverse(mat_inv_test)); |
| 313 | + // 验证特征值, 特征向量 |
| 314 | + int i; |
| 315 | + Matrix * lamda_I = M_I(target->row); |
| 316 | + for(i =0;i<lamda_I->row;i++){ |
| 317 | + lamda_I->data[i*(lamda_I->column)+i]=M_eigen_val_vec[val]->data[i]; |
| 318 | + } |
| 319 | + printf("->> (A*x - lamda*x) ?= 0(M_Zeros) \n"); |
| 320 | + // [Note.] lamda*x 为对特征向量(列存储), 进行列变换, 所以表示为: M_mul(M_eigen_val_vec[vec], lamda_I). |
| 321 | + M_print(M_add_sub(1, M_mul(target,M_eigen_val_vec[vec]), |
| 322 | + 1, M_mul(M_eigen_val_vec[vec], lamda_I))); |
| 323 | + M_free(M_eigen_val_vec[val]); |
| 324 | + M_free(M_eigen_val_vec[vec]); |
| 325 | + M_free(lamda_I); |
| 326 | + free(M_eigen_val_vec); |
| 327 | + // 验证SVD分解, U*Dia*(V.T) ?= A. |
| 328 | + printf("->> U*Dia*(V.T) ?= A \n"); |
| 329 | + Matrix * mat_SVD_dia = M_Zeros(mat_1->row, mat_1->column); |
| 330 | + for(i=0;i<mat_1->row;i++){ |
| 331 | + mat_SVD_dia->data[i*(mat_SVD_dia->column)+i] = mat_list_SVD[Dia]->data[i]; |
| 332 | + } |
| 333 | + M_print(mat_1); // A |
| 334 | + M_print(M_mul( |
| 335 | + M_mul(mat_list_SVD[U], |
| 336 | + mat_SVD_dia), |
| 337 | + M_T(mat_list_SVD[V]) |
| 338 | + )); // U*Dia*(V.T) |
| 339 | + M_free(mat_SVD_dia); |
| 340 | + M_free(mat_list_SVD[U]); |
| 341 | + M_free(mat_list_SVD[Dia]); |
| 342 | + M_free(mat_list_SVD[V]); |
| 343 | + free(mat_list_SVD); |
| 344 | + // 验证QR分解, Q*R?= A. |
| 345 | + printf("->> (Q*R) ?= A \n"); |
| 346 | + M_print(Hilbert(5)); |
| 347 | + M_print(M_mul(M_Q_R[q], M_Q_R[r])); |
| 348 | + M_free(M_Q_R[q]); |
| 349 | + M_free(M_Q_R[r]); |
| 350 | + free(M_Q_R); |
| 351 | + // 验证伪逆 pinv, A*A_pinv ?= I. |
| 352 | + printf("->> A*A_pinv ?= I \n"); |
| 353 | + M_print(M_mul(mat_1,mat_pinv)); |
| 354 | + |
| 355 | +/* [Others]*/ |
| 356 | + // Free Memory of Matrix, 释放矩阵内存. |
| 357 | + M_free(_mat_T); |
| 358 | + |
| 359 | +/* [Help]*/ |
| 360 | +// help 函数 |
| 361 | + // help("help"); |
| 362 | + // help("M_free"); |
| 363 | + // help("Update"); |
| 364 | + help("MatrixHub"); |
| 365 | + |
| 366 | + return 0; |
| 367 | +} |
0 commit comments