fork(1) download
  1. #include <iostream>
  2. #include <vector>
  3. #include <stdlib.h>
  4. #include <string>
  5. #include <math.h> //fabs
  6.  
  7.  
  8. /* TO BE DONE
  9.  - need to check operations perform correctly
  10.  */
  11.  
  12. /*create a matrix input string of form [1,2,3][4,5,6][7,8,9] - or allow commas between brackets, [],[],[] (they are ignored) or add B vector - [1,2,3|1][4,5,6|2][7,8,9|3]
  13. take input in as string and convert it to a vector<T> A and vector<T> B inside of the mtx class
  14.  
  15. if the format works (implicitly) then the matrix should read it in - otherwise it should try a different form
  16. */
  17.  
  18. class line;
  19.  
  20. ////////////////////////////////////////////////////////////////////////////////
  21. //CLASS MTX DEFINITION
  22. template <class T>
  23. class mtx
  24. {
  25. private:
  26. friend class line;
  27. std::vector<T> A; //matrix
  28. std::vector<T> B; //solution vector - size = number of rows for matrix - not necessary for some matrix operations
  29. std::size_t width;
  30. std::size_t height;
  31. std::size_t x, y;
  32. //PRIVATE FUNCTIONS
  33. bool isMatrixSquare(); //handles an error
  34. void swapRows (int first_in, int second_in);
  35. class line
  36. {
  37. mtx * p_mtx;
  38. public:
  39. line(mtx *p_mtx_in);
  40. T& operator [] (std::size_t y_in);
  41. const T& operator [] (std::size_t y_in) const;
  42. };
  43. public:
  44. //CONSTRUCTORS
  45. mtx ();
  46. mtx (std::vector<T>& Ain, std::vector<T>& Bin);
  47. //INDEX ACCESS OPERATOR OVERLOADS
  48. line& operator [] (std::size_t index);
  49. T& operator () (std::size_t x_in, std::size_t y_in);
  50. const T& operator () (std::size_t x_in, std::size_t y_in) const;
  51. //MATRIX PUBLIC FUNCTIONS
  52. mtx operator = (mtx& in); //ASSIGNMENT OPERATOR
  53. T& at (int i, int j);
  54.  
  55. friend void swap(mtx<T>& first_in, mtx<T>& second_in);
  56. //UNARY FUNCTIONS
  57. mtx& operator += (const mtx& rhs);
  58. mtx& operator -= (const mtx& rhs);
  59. mtx& operator *= (const mtx& rhs);
  60. //BINARY FUNCTIONS
  61. mtx operator + (const mtx& rhs);
  62. mtx operator - (const mtx& rhs);
  63. mtx operator * (const mtx& rhs);
  64. mtx operator * (const T& rhs); //scalar multiplication
  65.  
  66. //void Apush_back (double);
  67. //double Aat (int row, int col); //reads element at row,col where 0,0 is the first element in the matrix
  68. //void Bpush_back (double);
  69. //double Bat (int x);
  70. //bool
  71. //T determinant(); //calculates the determinant of square matrix
  72. mtx inverse(); //returns the inverse matrix
  73. void rref (); //Reduce Row Echelon Form - basic solution for square matrix
  74. void print();
  75.  
  76. /*at some point more functions will be added but this should be enough for the beam calc
  77. void inverse (void);
  78. void eigen (void);
  79. mtx operator* (mtx const rhs&); //A = B*C
  80. mtx& operator*= (mtx const rhs&);
  81.  
  82. */
  83. private:
  84. line m_line;
  85. };
  86.  
  87. ////////////////////////////////////////////////////////////////////////////////
  88. //MATRIX CLASS DECLARATION
  89. //PRIVATE FUNCTIONS*************************************************************
  90. template <class T>
  91. bool mtx<T>::isMatrixSquare()
  92. {
  93. if (width == height)
  94. {
  95. return true;
  96. }
  97. std::cerr << "ERROR at bool mtx<T>::isMatrixSquare() - matrix is not square." << std::endl;
  98. return false;
  99. }
  100. template <class T>
  101. void mtx<T>::swapRows (int row1_in, int row2_in)
  102. {
  103. if (row1_in >= height || row2_in >= height)
  104. {
  105. std::cerr <<"Error - row parameters not within matrix and vector dimension";
  106. return;
  107. }
  108. T temp;
  109. for (int i; i < width; i++)
  110. {
  111. temp = A[i + row1_in * width];
  112. A[i + row1_in * width] = A[i + row2_in * width];
  113. A[i + row2_in * width] = temp;
  114. }
  115. temp = B.at(row1_in); //swaps values in Bvector
  116. B.at(row1_in) = B.at(row2_in);
  117. B.at(row2_in) = temp;
  118. return;
  119. }
  120. template <class T>
  121. T& mtx<T>::line::operator [] (std::size_t y_in)
  122. {
  123. if (y_in >= p_mtx->height)
  124. {
  125. std::cerr << "row value is out of bounds and will be replaced with 0";
  126. p_mtx->y = 0;
  127. }
  128. else
  129. {
  130. p_mtx->y = y_in;
  131. }
  132. return p_mtx->A[p_mtx->x+p_mtx->y*p_mtx->width];
  133. }
  134. template <class T>
  135. const T& mtx<T>::line::operator [] (std::size_t y_in) const
  136. {
  137. if (y_in >= p_mtx->height)
  138. {
  139. std::cerr << "row value is out of bounds and will be replaced with 0";
  140. p_mtx->y = 0;
  141. }
  142. else
  143. {
  144. p_mtx->y = y_in;
  145. }
  146. return p_mtx->A[p_mtx->x+p_mtx->y*p_mtx->width];
  147. }
  148. //MATRIX CLASS CONSTRUCTORS*****************************************************
  149. template <class T>
  150. mtx<T>::mtx ():A(), B(), width(0), height(0), m_line(this)
  151. {
  152.  
  153. }
  154. template <class T>
  155. mtx<T>::mtx (std::vector<T>& Ain, std::vector<T>& Bin):A(Ain), B(Bin), m_line(this)
  156. {
  157. std::cout << "constructor started" <<std::endl;
  158. if(Ain.size() != 0 && Bin.size() != 0 && Ain.size() % Bin.size() == 0)
  159. {
  160. height = Bin.size();
  161. width = Ain.size()/height;
  162. }
  163. else
  164. {
  165. std::cerr << "Error - Matrix A and Vector B are of incompatible sizes - dummy matrix created";
  166. A.clear();
  167. B.clear();
  168. }
  169. }
  170. //MATRIX CLASS ACCESS OPERATOR OVERLOADS****************************************
  171. template <class T>
  172. typename mtx<T>::line& mtx<T>::operator [] (std::size_t x_in)
  173. {
  174. if (x_in >= width)
  175. {
  176. std::cerr << "row coordinate is out of bounds - setting to 0";
  177. x = 0;
  178. }
  179. else
  180. {
  181. x = x_in;
  182. }
  183. return m_line;
  184. }
  185. template <class T>
  186. T& mtx<T>::operator () (std::size_t x_in, std::size_t y_in)
  187. {
  188. return A[x_in + y_in * width];
  189. }
  190. template <class T>
  191. const T& mtx<T>::operator () (std::size_t x_in, std::size_t y_in) const
  192. {
  193. return A[x_in + y_in * width];
  194. }
  195. //MATRIX CLASS - UNARY FUNCTION OVERLOADS
  196. template <class T>
  197. mtx<T>& mtx<T>::operator += (const mtx& rhs)
  198. {
  199. if (height != rhs.height || width != rhs.width)
  200. {
  201. std::cerr << "ERROR at mtx& mtx<T>::operator += (const mtx& rhs) - matrix sizes do not match. No addition performed." << std::endl;
  202. return *this;
  203. }
  204. for (int i = 0; i<= A.size(); i++)
  205. {
  206. A[i] += rhs.A[i];
  207. }
  208. return *this;
  209. }
  210. template <class T>
  211. mtx<T>& mtx<T>::operator -= (const mtx& rhs)
  212. {
  213. if (height != rhs.height || width != rhs.width)
  214. {
  215. std::cerr << "ERROR at mtx& mtx<T>::operator -= (const mtx& rhs) - matrix sizes do not match. No subtraction performed." << std::endl;
  216. return *this;
  217. }
  218. for (int i = 0; i<= A.size(); i++)
  219. {
  220. A[i] -= rhs.A[i];
  221. }
  222. return *this;
  223. }
  224. template <class T>
  225. mtx<T>& mtx<T>::operator *= (const mtx& rhs)
  226. {
  227. if (width != rhs.height)
  228. {
  229. std::cout << "ERROR at mtx& mtx<T>::operator *= (const mtx& rhs) - matrix sizes are not compatible. No multiplication performed." << std::endl;
  230. return *this;
  231. }
  232. //create new matrix then swap with this
  233. std::vector<T> Atemp;
  234. std::vector<T> Btemp(0,height);
  235. for (int j = 0; j < height; j++)//use j for height in this and width in rhs
  236. {
  237. for (int i = 0; i < rhs.width; i++)
  238. {
  239. T mtxValue = 0;
  240. for (int n = 0; n < width; n++)
  241. {
  242. mtxValue += A[n+j*width] * rhs(i,n);
  243. }
  244. Atemp.push_back (mtxValue);
  245. }
  246. }
  247. mtx<T> temp(Atemp, Btemp);
  248. //swap(*this, temp);
  249. return temp;
  250. }
  251.  
  252.  
  253.  
  254.  
  255.  
  256. template <class T>
  257. T& mtx<T>::at (int x_in, int y_in)
  258. {
  259. return this->A.at(x_in + y_in * width);
  260. }
  261.  
  262.  
  263.  
  264. template <class T>
  265. void mtx<T>::rref ()
  266. {
  267. //WHAT HAPPENS WHEN WE HAVE MORE COLUMNS THAN ROWS?
  268. //MORE ROWS THAN COLUMNS?
  269. //WHEN A COLUMN DOESNT HAVE A 1 ON THE DIAGONAL
  270. if(A.size() == 0 || B.size() == 0 || A.size() % B.size() != 0)
  271. {
  272. std::cerr << "ERROR at [void mtx<T>::rref ()] - Matrix A and Vector B are of incompatible sizes - RREF not performed";
  273. return;
  274. }
  275. T largest, coefficient;
  276. int largestRow, count;
  277. count = 0;
  278. for (int i = 0; i< width; i++) //iterate through each column
  279. {
  280. largest = 0;
  281. for (int j = count; j < height; j++) //find largest in each row
  282. {
  283. if (fabs(A[i + j * width]) > largest)
  284. {
  285. largest = fabs(A[i + j * width]);
  286. largestRow = j;
  287. }
  288. }
  289. if (largestRow != count) //not on the diagonal then swap it onto the diagonal
  290. {
  291. this->swapRows(largestRow, count);
  292. }
  293. if (i != height && largest != 0) //if largest is 0 then skip
  294. {
  295. for (int k = 0; k < height; k++) //iterate through rows and 0 out column
  296. {
  297. if (k != count) //skip over diagonal
  298. {
  299. coefficient = -A[i + k * width]/A[i + i * width];
  300. std::cout << "coefficient = " << coefficient << std::endl;
  301. A[i + k * width] = 0; //first coefficient is 0 - no need to calc
  302. for (int m = i + 1; m < width; m++) //iterate across width
  303. {
  304. A[m + k * width] += A[m + i * width] * coefficient;
  305. }
  306. B[k] += B[i] * coefficient;
  307. }
  308. }
  309. this->print();
  310. }
  311. if (A[i + i * width] != 0) //set diagonal value to 1
  312. {
  313. coefficient = 1.0 / A[i + i * width];
  314. A[i + i * width] = 1.0;
  315. for (int n = i + 1; n < width; n++)
  316. {
  317. A[n + i * width] *= coefficient;
  318. }
  319. B[i] *= coefficient;
  320. count++;
  321. if (count == width || count == height)
  322. {
  323. return;
  324. }
  325. }
  326. }
  327. }
  328.  
  329. template <class T>
  330. mtx<T>::line::line (mtx * p_mtx_in):p_mtx(p_mtx_in)
  331. {
  332.  
  333. }
  334.  
  335. template <class T>
  336. void swap (mtx<T>& first_in, mtx<T>& second_in)
  337. {
  338. using std::swap;
  339. swap(first_in.A, second_in.A);
  340. swap(first_in.B, second_in.B);
  341. swap(first_in.width, second_in.width);
  342. swap(first_in.height, second_in.height);
  343. swap(first_in.x, second_in.x);
  344. swap(first_in.y, second_in.y);
  345. swap(first_in.m_line, second_in.m_line);
  346. return;
  347. }
  348.  
  349. template <class T>
  350. void mtx<T>::print ()
  351. {
  352. for (int j=0; j<height; j++)
  353. {
  354. for (int i = 0; i<width; i++)
  355. {
  356. std::cout << A[i + j * width] << " ";
  357. }
  358. std::cout << "| " << B[j] << std::endl;
  359. }
  360. }
  361.  
  362. int main() {
  363. // your code goes here
  364. std::vector<double> atemp, btemp;
  365.  
  366. for (int i = 0; i < 12; i++)
  367. {
  368. atemp.push_back(double(pow(i,3)/4.12785));
  369. }
  370.  
  371. for (int i = 0; i < 3; i++)
  372. {
  373. btemp.push_back(double(4.0-i));
  374. }
  375. mtx<double> M (atemp, btemp);
  376. M.print();
  377. M *= M;
  378. M.rref();
  379. M.print();
  380. double pi = 3.14159;
  381. M [1][2] = pi;
  382. M(0,1) = pi;
  383. M.print();
  384. M.rref();
  385. M.print();
  386.  
  387. return 0;
  388. }
  389.  
Success #stdin #stdout 0s 15248KB
stdin
Standard input is empty
stdout
constructor started
0 0.242257 1.93805 6.54094 | 4
15.5044 30.2821 52.3275 83.0941 | 3
124.036 176.605 242.257 322.444 | 2
ERROR at mtx& mtx<T>::operator *= (const mtx& rhs) - matrix sizes are not compatible.  No multiplication performed.
coefficient = -0.125
coefficient = -0
124.036 176.605 242.257 322.444 | 2
0 8.20645 22.0454 42.7886 | 2.75
0 0.242257 1.93805 6.54094 | 4
coefficient = -0.173501
coefficient = -0.0295203
1 0 -1.87177 -4.82426 | -0.461004
0 8.20645 22.0454 42.7886 | 2.75
0 0 1.28727 5.2778 | 3.91882
coefficient = 1.45406
coefficient = -2.08686
1 0 0 2.85 | 5.23721
0 1 0 -5.8 | -7.84291
0 0 1.28727 5.2778 | 3.91882
1 0 0 2.85 | 5.23721
0 1 0 -5.8 | -7.84291
0 0 1 4.1 | 3.04429
1 0 0 2.85 | 5.23721
3.14159 1 0 -5.8 | -7.84291
0 3.14159 1 4.1 | 3.04429
coefficient = -0.31831
coefficient = -0
3.14159 1 0 -5.8 | -7.84291
0 -0.31831 0 4.6962 | 7.73369
0 3.14159 1 4.1 | 3.04429
coefficient = -0.101321
coefficient = 0.101321
1 0 -0.101321 -2.26162 | -2.80493
0 3.14159 1 4.1 | 3.04429
0 0 0.101321 5.11162 | 8.04214
coefficient = 1
coefficient = -3.14159
1 0 0 2.85 | 5.23721
0 1 0 -14.7535 | -24.2961
0 0 0.101321 5.11162 | 8.04214
1 0 0 2.85 | 5.23721
0 1 0 -14.7535 | -24.2961
0 0 1 50.4495 | 79.3726