fork download
  1. #include <iostream>
  2. #include <stdint.h>
  3. #include <stdio.h>
  4.  
  5. using namespace std;
  6.  
  7. // класс, реализующий матрицу
  8. class Matrix
  9. {
  10. public:
  11.  
  12. // конструктор по умолчанию
  13. Matrix()
  14. : mNumRows(0)
  15. , mNumCols(0)
  16. , mArr(0)
  17. {
  18. }
  19.  
  20. // конструктор, создающий реальную матрицу ненулевой размерности и заполняет начальным значением
  21. Matrix( int numRows, int numCols, double initValue )
  22. : mNumRows( 0 )
  23. , mNumCols( 0 )
  24. , mArr( 0 )
  25. {
  26. initArr( numRows, numCols, initValue );
  27. }
  28.  
  29. // конструктор копии - создающий матрицу как копию матрици-источника
  30. Matrix( Matrix& source )
  31. : mNumRows( source.mNumRows )
  32. , mNumCols( source.mNumCols )
  33. , mArr( 0 )
  34. {
  35. swap( source );
  36. }
  37.  
  38. // деструктор, необходим для удаления выделенного на куче двумерного массива
  39. ~Matrix()
  40. {
  41. resetArr();
  42. }
  43.  
  44. // переопределённый оператор присваивания, необходим для корректного присваивания матриц
  45. Matrix& operator=( Matrix& rhs )
  46. {
  47. swap( rhs );
  48. }
  49.  
  50. // возвращает число строк в матрице
  51. int getNumRows() { return mNumRows; };
  52.  
  53. // возвращает число колонок в матрице
  54. int getNumCols() { return mNumCols; };
  55.  
  56. // возвращает указатель на двумерный массив на куче, содержащий саму матрицу
  57. double** getArr() { return mArr; };
  58.  
  59. // копирует матрицу-источник в себя
  60. void swap( Matrix& another );
  61.  
  62. // создает левую диагональ, заполненную заданным значением
  63. void setLeftDiag( double value );
  64.  
  65. // суммирует другую матрицу с собой
  66. void sum( Matrix& another );
  67.  
  68. // возводит себя в n-ю степень
  69. void power( int n );
  70.  
  71. //выполняет произведение себя и другой матрицы, метод используется в методе power
  72. void product( Matrix& another );
  73.  
  74. // умножает себя на заданное значение
  75. void multiply( double& value );
  76.  
  77. // выводит на консоль содержимое себя, придворенное заголовком
  78. void show( const char* title );
  79.  
  80. // создает заново свой двумерный массив и заполняет заданным значеним, исп. в конструкторе
  81. void initArr( int numRows, int numCols, double initValue );
  82.  
  83. // удаляет двумерный массив из кучи и обнуляет указатель, исп. в деструкторе а также в initArr
  84. void resetArr();
  85.  
  86. private:
  87.  
  88. int mNumRows;
  89. int mNumCols;
  90. double** mArr;
  91. };
  92.  
  93. void Matrix::swap( Matrix& another )
  94. {
  95. initArr( another.mNumRows, another.mNumCols, 0 );
  96. for( int row = 0; row < mNumRows; row++ )
  97. {
  98. for( int col = 0; col < mNumCols; col++ )
  99. {
  100. mArr[ row ][ col ] = another.mArr[ row ][ col ];
  101. }
  102. }
  103. }
  104.  
  105. void Matrix::setLeftDiag( double value )
  106. {
  107. int n = min( mNumRows, mNumCols );
  108. for( int i = 0; i < n; i++ )
  109. {
  110. mArr[ i ][ i ] = value;
  111. }
  112. }
  113.  
  114. void Matrix::sum( Matrix& another )
  115. {
  116. int numRows = min( mNumRows, another.getNumRows() );
  117. int numCols = min( mNumCols, another.getNumCols() );
  118.  
  119. for( int row = 0; row < mNumRows; row++ )
  120. {
  121. for( int col = 0; col < mNumCols; col++ )
  122. {
  123. mArr[ row ][ col ] += another.mArr[ row ][ col ];
  124. }
  125. }
  126. }
  127.  
  128. void Matrix::power( int n )
  129. {
  130. for( int i = 1; i < n; i++ )
  131. {
  132. product( *this );
  133. }
  134. }
  135.  
  136. void Matrix::product( Matrix& another )
  137. {
  138.  
  139. if ( mNumCols != another.mNumRows )
  140. {
  141. printf( "*** Matrix::product: argument matrix is not complementary, production is impossible ***\n" );
  142. return;
  143. }
  144.  
  145. Matrix result( mNumRows, another.mNumCols, 0 );
  146.  
  147. for( int rowResult = 0; rowResult < result.mNumRows; rowResult++ )
  148. {
  149. for( int colResult = 0; colResult < result.mNumCols; colResult++ )
  150. {
  151. result.mArr[ rowResult ][ colResult ] = 0;
  152. for( int col = 0; col < mNumCols; col++ )
  153. {
  154.  
  155. result.mArr[ rowResult ][ colResult ] +=
  156. ( mArr[ rowResult ][ col ] * another.mArr[ col ][ colResult ] );
  157. }
  158. }
  159. }
  160.  
  161. swap( result );
  162. }
  163.  
  164. void Matrix::multiply( double& value )
  165. {
  166. for( int row = 0; row < mNumRows; row++ )
  167. {
  168. for( int col = 0; col < mNumCols; col++ )
  169. {
  170. mArr[ row ][ col ] *= value;
  171. }
  172. }
  173. }
  174.  
  175. void Matrix::show( const char* title )
  176. {
  177. printf("%s:\n", title);
  178.  
  179. for( int row = 0; row < mNumRows; row++ )
  180. {
  181. for( int col = 0; col < mNumCols; col++ )
  182. {
  183. printf("%10.04lf ", mArr[ row ][ col ] );
  184. }
  185. printf("\n");
  186. }
  187. }
  188.  
  189. void Matrix::initArr( int numRows, int numCols, double initValue )
  190. {
  191. resetArr();
  192. mNumRows = numRows;
  193. mNumCols = numCols;
  194. mArr = new double*[ mNumRows ]; // создает массив указателей на подмассивы колонок
  195. for( int row = 0; row < mNumRows; row++ )
  196. {
  197. mArr[ row ] = new double[ mNumCols ]; // создает подмассив колонок для данной строки
  198. for( int col = 0; col < mNumCols; col++ ) // заполняет подмассив колонок заданным значениям
  199. {
  200. mArr[ row ][ col ] = initValue;
  201. }
  202. }
  203. }
  204.  
  205. void Matrix::resetArr()
  206. {
  207. if ( mArr!= 0 )
  208. {
  209. for( int row = 0; row < mNumRows; row++ )
  210. {
  211. delete[] mArr[ row ];
  212. }
  213. delete [] mArr;
  214. mArr = 0;
  215. }
  216. }
  217.  
  218. //==============================================================================
  219.  
  220. // ввыд с консоли какого либо целого числа
  221. static int inputNumber( const char *title )
  222. {
  223. int n = 0;
  224.  
  225. printf("input %s:\n", title);
  226.  
  227. if ( scanf("%d", &n ) <= 0 )
  228. {
  229. printf("error input of %s\n",title);
  230. }
  231. else
  232. if ( n <= 0 )
  233. {
  234. printf("wrong %s value, must be positive\n", title);
  235. }
  236.  
  237. return n;
  238. }
  239.  
  240. // ввод с консоли содержимого какой либо матрицы
  241. static bool inputMatrixData( const char *title, Matrix& x )
  242. {
  243. printf("input %dx%d %s:\n", x.getNumRows(), x.getNumCols(), title );
  244.  
  245. for( int row = 0; row < x.getNumRows(); row++ )
  246. {
  247. for( int col = 0; col < x.getNumCols(); col++ )
  248. {
  249. double val = 0;
  250. if ( scanf("%lf", &val ) <= 0 )
  251. {
  252. printf("error input of %s\n",title);
  253. return false;
  254. }
  255. x.getArr()[ row ][ col ] = val;
  256.  
  257. }
  258. }
  259. return true;
  260. }
  261.  
  262. //==============================================================================
  263.  
  264. int main()
  265. {
  266. int numIter = inputNumber( "Number of iterations 'n'" );
  267. int sizeA = inputNumber( "matrix size 'm'" );
  268.  
  269. if ( numIter <= 0 || sizeA <= 0 )
  270. {
  271. return 0;
  272. }
  273.  
  274. Matrix mxP( 1, numIter, 0 ); // для хранения p_0, P_1, ... P_n
  275. if ( ! inputMatrixData( "P matrix values", mxP ) )
  276. {
  277. return 0;
  278. }
  279.  
  280. Matrix mxA( sizeA, sizeA, 0 );
  281. if ( ! inputMatrixData( "A matrix values", mxA ) )
  282. {
  283. return 0;
  284. }
  285.  
  286. Matrix mxE( sizeA, sizeA, 0 );
  287. mxE.setLeftDiag( 1 );
  288.  
  289. // печатаем исходные данные перед вычислением
  290. mxE.show("============= matrix E ==============");
  291. mxP.show("============= matrix P ==============");
  292. mxA.show("============= matrix A ==============");
  293.  
  294. Matrix s; // это будет общая сумма полинома
  295.  
  296. s.swap( mxE );
  297.  
  298. s.multiply( mxP.getArr()[0][0] ); // создает P_0*E, как начальное значение суммирования
  299.  
  300. // главный цикл суммирования полинома
  301. for( int i = 1; i < numIter; i++ )
  302. {
  303.  
  304. Matrix x; // это будет временная матрица для вычисления одного слагаемого полинома (pow(A,i)*P_i*E)
  305. x.swap( mxA ); // копируем содержимое матрицы A
  306.  
  307. x.power( i ); // возводим x в степень i, т.е. pow(A,i)
  308.  
  309. x.multiply( mxP.getArr()[0][i] ); // умножаем x на коэфф. p_i , т.е. полуйчаем результат одного слогаемого (pow(A,i)*P_i)
  310.  
  311. s.sum( x ); // накапливаем сумму полинома
  312.  
  313. }
  314.  
  315. s.show("============= result: ==============");// печатаем результат вычисления полинома
  316.  
  317. return 0;
  318. }
Success #stdin #stdout 0s 3148KB
stdin
Standard input is empty
stdout
input Number of iterations 'n':
error input of Number of iterations 'n'
input matrix size 'm':
error input of matrix size 'm'