CalculEquation.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #include "pch.h"
  2. #include "CalculEquation.h"
  3. CalculEquation::CalculEquation()
  4. {
  5. m_nNodeMatricCol = NODE_MATRIC_COLLOM;
  6. m_nNodeMatricRow = NODE_MATRIC_ROW;
  7. a=new double *[m_nNodeMatricRow];
  8. for (int aindex=0;aindex< m_nNodeMatricRow;aindex++)
  9. {
  10. a[aindex]=new double [m_nNodeMatricCol];
  11. }
  12. b=new double *[m_nNodeMatricRow];
  13. for (int bindex=0;bindex < m_nNodeMatricRow;bindex++)
  14. {
  15. b[bindex]=new double [m_nNodeMatricCol];
  16. }
  17. /*
  18. for(int aXindex=0;aXindex<NODE_MATRIC_ROW;aXindex++)
  19. {
  20. vector<long double> va;
  21. for (int aYindex=0;aYindex<NODE_MATRIC_COLLOM;aYindex++)
  22. {
  23. va.push_back(0.0);
  24. }
  25. a.push_back(va);
  26. }
  27. for(int bXindex=0;bXindex<NODE_MATRIC_ROW;bXindex++)
  28. {
  29. vector<long double> vb;
  30. for (int bYindex=0;bYindex<NODE_MATRIC_COLLOM;bYindex++)
  31. {
  32. vb.push_back(0.0);
  33. }
  34. b.push_back(vb);
  35. }*/
  36. }
  37. CalculEquation::~CalculEquation()
  38. {
  39. Clear();
  40. if (b!=NULL)
  41. {
  42. for (int bindex = m_nNodeMatricRow -1;bindex>=0;bindex--)
  43. {
  44. if (b[bindex]==NULL)
  45. {
  46. continue;
  47. }
  48. delete []b[bindex];
  49. b[bindex]=NULL;
  50. }
  51. delete []b;
  52. b=NULL;
  53. }
  54. if (a!=NULL)
  55. {
  56. for (int aindex = m_nNodeMatricRow -1;aindex>=0;aindex--)
  57. {
  58. if (a[aindex]==NULL)
  59. {
  60. continue;
  61. }else
  62. {
  63. if (aindex==1)
  64. {
  65. double* test=a[aindex];
  66. for (int xs=0;xs< m_nNodeMatricCol;xs++)
  67. {
  68. //delete a[aindex];
  69. double pi=*(test+xs);
  70. pi=0.0;
  71. }
  72. //delete []a[aindex];
  73. }else
  74. {
  75. delete []a[aindex];
  76. }
  77. a[aindex]=NULL;
  78. }
  79. }
  80. delete []a;
  81. a=NULL;
  82. }
  83. }
  84. void CalculEquation::chengplus(int i,const double k, int j)//i行乘k加到j行
  85. {
  86. for(int t=0;t<lie;t++)
  87. {
  88. b[j-1][t]+=b[i-1][t]*k;
  89. }
  90. }
  91. void CalculEquation::chengk(int i,const double k)//i行乘k
  92. {
  93. for(int c=0;c<lie;c++)
  94. {
  95. b[i-1][c]=b[i-1][c]*k;
  96. }
  97. }
  98. void CalculEquation::exchange(int i, int j)//i行与j行互换
  99. {
  100. long double temp=0;
  101. for(int t=0;t<lie;t++)
  102. {
  103. temp=b[i-1][t];
  104. b[i-1][t]=b[j-1][t];
  105. b[j-1][t]=temp;
  106. }
  107. }
  108. void CalculEquation::SetParam(int hang,int lie,const double ratio)//行列参数设置,给矩阵对应位置的元素赋值, //设置节点导纳+电流矩阵中的各节点自导、互导、注入电流参数 xyx注释
  109. {
  110. double inData=ratio;
  111. if (a[hang]!=NULL)
  112. {
  113. a[hang][lie]=inData; //将节点导纳+注入电流矩阵赋给a阵
  114. }
  115. }
  116. void CalculEquation::hualie(int i) //函数的具体功能:对第i列的第i行前的元素乘k运算,第i行后的元素:将第i行的元素乘kkk加到对应的第i行的对应元素
  117. {
  118. int jilu=-1;
  119. for(int v=0;v<(hang-i+1);v++) //对第i列元素的第i行后的元素进行处理,
  120. {
  121. if(b[i-1+v][i-1]!=0) //判断第i列元素的第i行后的元素是否非零 //主对角线及下三角元素 xyx注释
  122. {
  123. jilu=i+v;
  124. break;
  125. }
  126. }
  127. if(jilu==-1)
  128. {
  129. }
  130. else //对非零元素进行处理
  131. {
  132. long double kkk=1;
  133. exchange(i,jilu);//第i行与第jilu行交换 //第一步:交换矩阵的两行,进行行交换后尽量使主对角线非零且下三角为元素为0 xyx注释
  134. chengk(i,(1.0/b[i-1][i-1]));//对第i行的元素乘k //对第i行元素归一化 2016.03.18 //第二步:用非零常数乘矩阵的某行,将主对角元素归一化 xyx注释
  135. for(int w=0;w<(hang-i);w++)//对第i行前面的元素进行判断
  136. {
  137. if(b[i-1][i-1]!=0)//行列元素坐标为(i,i)的非零判断
  138. {
  139. kkk=0.0-(b[i+w][i-1]/b[i-1][i-1]);
  140. chengplus(i,kkk,i+1+w);//第i-1行乘kkk加到i+w行 //第三步:用常数乘矩阵的某行,加到其它的行上 xyx注释
  141. }
  142. }
  143. }
  144. }
  145. void CalculEquation::Uhualie(int i)//?此函数的功能和作用
  146. {
  147. if(b[i-1][i-1]!=0)//第i行第i列元素非零判断
  148. {
  149. long double kkk=1;
  150. for(int w=0;w<(i-1);w++)
  151. {
  152. if(b[i-1][i-1]!=0)
  153. {
  154. kkk=0.0-(b[i-2-w][i-1]/b[i-1][i-1]);//?这里有具体的公式存在不?
  155. chengplus(i,kkk,i-1-w);//将第i行第i列的元素乘kkk(随w的值变化而变化)加到第i列第i-1-w行上
  156. }
  157. }
  158. }
  159. }
  160. void CalculEquation::jisuan()//
  161. {//详细注释此函数的功能和作用:
  162. if (a==NULL||b==NULL)
  163. {
  164. return;
  165. }
  166. for(int i=0;i < m_nNodeMatricRow;i++)
  167. {
  168. for(int j=0;j< m_nNodeMatricCol;j++)
  169. {
  170. b[i][j]=a[i][j]; //将a矩阵参数赋给b矩阵,此时矩阵中存放直流节点的自导、互导、注入电流值
  171. }
  172. }
  173. int z=0;
  174. if(hang<lie) //z=行数、列数中的较小者,此处z取行数 xyx注释
  175. {
  176. z=hang;
  177. }
  178. else
  179. {
  180. z=lie;
  181. }
  182. //以下函数的功能为:矩阵初等行变换法求逆: xyx注释
  183. //第一步:交换矩阵的两行,各非零行的第一个非零元素的列标随着行标的增大而严格增大,形成阶梯矩阵
  184. //第二步:用一非零常数乘矩阵的某行
  185. //第三步:用常数乘矩阵的某行,加到其它的行上
  186. for(int zi=0;zi<z;zi++)//对矩阵维数较小的列进行划列(顺序)
  187. {
  188. hualie(zi+1);
  189. }
  190. for(int zii=0;zii<z;zii++)//对矩阵维数较小的列进行优化(逆序)
  191. {
  192. Uhualie(z-zii);
  193. }
  194. for(int zck=0;zck<z;zck++)
  195. {
  196. if(b[zck][zck]!=0)
  197. {
  198. chengk(zck+1,(1.0/b[zck][zck]));//对第zck+1行元素乘(1.0/b[zck][zck])运算
  199. }
  200. }
  201. }
  202. void CalculEquation::Clear()//矩阵清零 //矩阵初始化清零,将所有元素值设为0 xyx注释
  203. {
  204. if (a==NULL||b==NULL)
  205. {
  206. return;
  207. }
  208. for(int i=0;i < m_nNodeMatricRow;i++)
  209. {
  210. if (a[i] != NULL)
  211. {
  212. for(int j=0;j< m_nNodeMatricCol;j++)
  213. {
  214. a[i][j]=0.0;
  215. }
  216. }
  217. if (b[i] != NULL)
  218. {
  219. for(int j=0;j< m_nNodeMatricCol;j++)
  220. {
  221. b[i][j]=0.0;
  222. }
  223. }
  224. }
  225. }
  226. void CalculEquation::SetHangLie(int h,int l)//设置行列
  227. {
  228. hang = h;
  229. lie=l;
  230. };
  231. BOOL CalculEquation::CheckResult() //验证结果的正确性(很想知道这个函数的具体意义是什么?)
  232. {
  233. int testa=0;
  234. int testb=0;
  235. //double bbvalue[17];
  236. for(int i=0;i<hang;i++)
  237. {
  238. for(int j=0;j<hang;j++)
  239. {
  240. if(b[i][j]!=0) //判断求出的逆矩阵第i行各元素是否非零:节点导纳矩阵的逆矩阵 xyx注释
  241. {
  242. testb+=1; //(1)若存在非零元素,则进行计数testb+=1;(2)若前lie-1列的元素全为零,则testb==0 xyx注释
  243. }
  244. }
  245. double bvalue = b[i][lie-1]; //第i行的最后一列元素:节点注入电流bvalue xyx注释
  246. // bbvalue[i] = b[i][lie-1];///
  247. if(testb==0&&b[i][lie-1]!=0) //若第i行的前lie-1列的元素全为0,且最后一列元素!=0,则说明该行的方程无解,并进行计数testa+=1 xyx注释
  248. {
  249. int ivalue = i;
  250. testa+=1;
  251. }
  252. testb=0;
  253. }
  254. if(testa!=0) //testa!=0,说明该行的方程无解,计算错误 xyx注释
  255. {
  256. return FALSE;
  257. }
  258. return TRUE;
  259. }