fork download
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <cassert>
  5. #include <ctime>
  6.  
  7. #define USE_CPP11
  8. //------------------------------------------------
  9. template<typename T>
  10. class Matrix;
  11. //--------------- friends forward define --------------------------
  12. template<typename T>
  13. std::ostream& operator<<(std::ostream& stream,const Matrix<T>& m);
  14.  
  15. template<typename T>
  16. std::istream& operator>>(std::istream& stream,Matrix<T>& m);
  17.  
  18. template<typename T>
  19. Matrix<T> operator*(const Matrix<T>& m,const T& value);
  20.  
  21. template<typename T>
  22. Matrix<T> operator/(const Matrix<T>& m,const T& value);
  23.  
  24. template<typename T>
  25. Matrix<T> operator*(const T& value,const Matrix<T>& m);
  26.  
  27. template<typename T>
  28. Matrix<T> operator/(const T& value,const Matrix<T>& m);
  29. //---------------- Proxy class row --------------------------------
  30. template<typename T>
  31. class Row
  32. {
  33. friend class Matrix<T>;
  34.  
  35. public:
  36. Row(std::size_t size=0);
  37. ~Row();
  38.  
  39. T& operator[](std::size_t c);
  40. const T& operator[](std::size_t c)const;
  41.  
  42. Row operator+(const Row& other)const;
  43. Row operator-(const Row& other)const;
  44.  
  45. private:
  46. // hidden member function, used only Matrix<T>
  47.  
  48. Row(const Row& row);
  49. // Row& operator=(const Row& row);
  50.  
  51. void swap(Row& row);
  52.  
  53. #ifdef USE_CPP11
  54. Row(Row&& row);
  55. Row& operator=(Row&& row);
  56. #endif
  57.  
  58. void clear();
  59. void recreate(std::size_t size);
  60.  
  61. private:
  62. T* data_;
  63. };
  64. //-----------------------------------------
  65. // public
  66. //-----------------------------------------
  67. template<typename T>
  68. T& Row<T>::operator[](std::size_t c)
  69. {
  70. return data_[c];
  71. }
  72.  
  73. template<typename T>
  74. const T& Row<T>::operator[](std::size_t c)const
  75. {
  76. return data_[c];
  77. }
  78. //-----------------------------------------
  79. // private
  80. //-----------------------------------------
  81. template<typename T>
  82. Row<T>::Row(std::size_t size)
  83. :data_(0)
  84. {
  85. if(size)
  86. data_= new T[size];
  87. }
  88.  
  89. //template<typename T>
  90. //Row<T>& Row<T>::operator=(const Row<T>& row)
  91. //{
  92. // if(data!=row.data_)
  93. // {
  94. // clear();
  95. // ???
  96. // }
  97. // return *this;
  98. //}
  99. //-------------------------------------------
  100. template<typename T>
  101. void Row<T>::swap(Row<T>& row)
  102. {
  103. std::swap(data_,row.data_);
  104. }
  105. //-------------------------------------------
  106. #ifdef USE_CPP11
  107. //-------------------------------------------
  108. template<typename T>
  109. Row<T>::Row(Row<T>&& row)
  110. :Row<T>()
  111. {
  112. this->swap(row);
  113. }
  114.  
  115. template<typename T>
  116. Row<T>& Row<T>::operator=(Row<T>&& row)
  117. {
  118. this->swap(row);
  119. return *this;
  120. }
  121. //-------------------------------------------
  122. #endif
  123. //-------------------------------------------
  124. template<typename T>
  125. Row<T>::~Row()
  126. {
  127. clear();
  128. }
  129.  
  130. template<typename T>
  131. void Row<T>::clear()
  132. {
  133. delete[] data_;
  134. data_ = 0;
  135. }
  136.  
  137. template<typename T>
  138. void Row<T>::recreate(std::size_t size)
  139. {
  140. clear();
  141. data_= new T[size];
  142. }
  143. //-------------------------------------------
  144. // Matrix
  145. //-------------------------------------------
  146. template<typename T>
  147. class Matrix
  148. {
  149. public:
  150. Matrix();
  151. Matrix(std::size_t rowSize,std::size_t colSize=1);
  152. ~Matrix();
  153.  
  154. Matrix(const Matrix& m);
  155. Matrix& operator=(const Matrix& m);
  156.  
  157. void clear();
  158. void resize(std::size_t rowSize,std::size_t colSize);
  159.  
  160. bool empty()const;
  161. void swap(Matrix& m);
  162.  
  163. #ifdef USE_CPP11
  164. Matrix(Matrix&& m);
  165. Matrix& operator=(Matrix&& m);
  166.  
  167. Matrix(const std::initializer_list<T>& list, bool horizontal=false);
  168. Matrix(const std::initializer_list<std::initializer_list<T> >& list);
  169. #endif
  170.  
  171. Row<T>& operator[](std::size_t r);
  172. const Row<T>& operator[](std::size_t r)const;
  173.  
  174. bool operator==(const Matrix& m)const;
  175.  
  176. std::size_t rowSize()const;
  177. std::size_t colSize()const;
  178.  
  179. bool isSquare() const;
  180.  
  181. void fill(const T& value);
  182.  
  183. Matrix operator+(const Matrix& m)const;
  184. Matrix operator-(const Matrix& m)const;
  185.  
  186. Matrix operator!() const; // Inverse
  187. Matrix operator~() const; // Transpose
  188.  
  189. // friends
  190. friend Matrix operator*<T>(const Matrix& m,const T& value);
  191. friend Matrix operator/<T>(const Matrix& m,const T& value);
  192.  
  193. friend Matrix operator*<T>(const T& value,const Matrix& m);
  194. friend Matrix operator/<T>(const T& value,const Matrix& m);
  195.  
  196. friend std::ostream& operator<< <T>(std::ostream& stream,const Matrix& m);
  197. friend std::istream& operator>> <T>(std::istream& stream,Matrix& m);
  198. //
  199. bool canMultiply(const Matrix& m)const;
  200. Matrix operator*(const Matrix& m)const;
  201.  
  202.  
  203. T det()const;
  204.  
  205. void inverse();
  206. Matrix inversed()const;
  207.  
  208. T& item(int row, int col); // note slice ??
  209. const T& item(int row, int col)const;
  210.  
  211. // Matrix operator/(const Matrix& m)const;
  212.  
  213. // Matrix& operator+=(const Matrix& m);
  214.  
  215. // Matrix& operator-=(const Matrix& m);
  216. // Matrix& operator*=(const Matrix& m);
  217. // Matrix& operator/=(const Matrix& m);
  218. // Matrix& operator*=(const T& value);
  219. // Matrix& operator/=(const T& value);
  220.  
  221. void transponde();
  222. Matrix transponded()const;
  223.  
  224. Matrix minor(std::size_t r,std::size_t c)const;
  225. T minor_det(std::size_t row,std::size_t col)const;
  226.  
  227. T addition(std::size_t r,std::size_t c) const;
  228.  
  229. private:
  230. Row<T>* data_;
  231. std::size_t rowSize_;
  232. std::size_t colSize_;
  233. };
  234. //------------------------------------------------
  235. template<typename T, std::size_t size,std::size_t colSize>
  236. Matrix<T> fromArray(const T (&a)[size][colSize])
  237. {
  238. Matrix<T> rm(colSize,size);
  239. for(std::size_t r=0; r<size; ++r)
  240. for(std::size_t c=0; c<colSize; ++c)
  241. rm[c][r]= a[c][r];
  242. return rm;
  243. }
  244. //------------------------------------------------
  245. template<typename T, std::size_t size>
  246. Matrix<T> fromArray(const T (&a)[size],bool horizontal=true)
  247. {
  248. Matrix<T> rm(horizontal?size:1,
  249. horizontal?1:size);
  250.  
  251. for(std::size_t i=0; i<size; ++i)
  252. if(horizontal)
  253. rm[i][0]= a[i];
  254. else
  255. rm[0][i]= a[i];
  256. return rm;
  257. }
  258. //------------------------------------------------
  259. template<typename T>
  260. Matrix<T>::Matrix()
  261. :data_(0),
  262. rowSize_(0),
  263. colSize_(0)
  264. {
  265. }
  266. //------------------------------------------------
  267. template<typename T>
  268. Matrix<T>::Matrix(std::size_t rowSize,
  269. std::size_t colSize)
  270. :rowSize_(rowSize),
  271. colSize_(colSize)
  272. {
  273. data_= new Row<T>[rowSize_];
  274. for(std::size_t r=0; r<rowSize_; ++r)
  275. data_[r].recreate(colSize_);
  276. }
  277.  
  278. template<typename T>
  279. Matrix<T>::Matrix(const Matrix<T>& m)
  280. {
  281. rowSize_= m.rowSize_;
  282. colSize_= m.colSize_;
  283.  
  284. data_= new Row<T>[rowSize_];
  285. for(std::size_t r=0; r<rowSize_; ++r)
  286. data_[r].recreate(colSize_);
  287.  
  288. for(std::size_t r=0; r<rowSize_; ++r)
  289. for(std::size_t c=0; c<colSize_; ++c)
  290. data_[r][c]= m.data_[r][c];
  291. }
  292.  
  293. template<typename T>
  294. Matrix<T>& Matrix<T>::operator=(const Matrix<T>& m)
  295. {
  296. if(data_==m.data_)
  297. return *this;
  298.  
  299. resize(m.rowSize_,m.colSize_);
  300.  
  301. for(std::size_t r=0; r<rowSize_; ++r)
  302. for(std::size_t c=0; c<colSize_; ++c)
  303. data_[r][c]= m.data_[r][c];
  304.  
  305. return *this;
  306. }
  307.  
  308.  
  309. template<typename T>
  310. void Matrix<T>::swap(Matrix<T>& m)
  311. {
  312. std::swap(data_,m.data_);
  313. std::swap(rowSize_,m.rowSize_);
  314. std::swap(colSize_,m.colSize_);
  315. }
  316. //----------------------------------------------------
  317. #ifdef USE_CPP11
  318. //----------------------------------------------------
  319. // move semantic
  320. //----------------------------------------------------
  321. template<typename T>
  322. Matrix<T>::Matrix(Matrix<T>&& m)
  323. :Matrix<T>()
  324. {
  325. this->swap(m);
  326. }
  327.  
  328. template<typename T>
  329. Matrix<T>& Matrix<T>::operator=(Matrix<T>&& m)
  330. {
  331. this->swap(m);
  332. return *this;
  333. }
  334. //----------------------------------------------------
  335. // initializer_list
  336. //----------------------------------------------------
  337. template<typename T>
  338. Matrix<T>::Matrix(const std::initializer_list<T>& list, bool horizontal)
  339. :Matrix<T>()
  340. {
  341. resize( horizontal ? 1 : list.size(), // row = 1
  342. horizontal ? list.size() : 1 ); // col = 1
  343.  
  344. for(std::size_t i=0; i<list.size(); ++i)
  345. if(horizontal)
  346. data_[0][i]= *(list.begin()+i);
  347. else
  348. data_[i][0]= *(list.begin()+i);
  349. }
  350.  
  351. template<typename T>
  352. Matrix<T>::Matrix(const std::initializer_list<std::initializer_list<T>>& list)
  353. :Matrix<T>()
  354. {
  355. resize(list.size(),list.begin()->size());
  356.  
  357. for(std::size_t r=0; r<rowSize_; ++r)
  358. for(std::size_t c=0; c<colSize_; ++c)
  359. data_[r][c]= *((list.begin()+r)->begin()+c);
  360. }
  361. //----------------------------------------------------
  362. #endif
  363. //----------------------------------------------------
  364. template<typename T>
  365. Matrix<T>::~Matrix()
  366. {
  367. clear();
  368. }
  369.  
  370. template<typename T>
  371. void Matrix<T>::clear()
  372. {
  373. delete[] data_;
  374. data_= 0;
  375. rowSize_ = 0;
  376. colSize_ = 0;
  377. }
  378.  
  379. template<typename T>
  380. void Matrix<T>::resize(std::size_t newRowSize,std::size_t newColSize)
  381. {
  382. if(newRowSize==rowSize_ && newColSize==colSize_)
  383. return;
  384.  
  385. if(newRowSize==0)
  386. {
  387. clear();
  388. return;
  389. }
  390. Matrix<T> m(newRowSize,newColSize);
  391.  
  392. // copy old data
  393. std::size_t minRowSize = std::min(newRowSize,rowSize_);
  394. std::size_t minColSize = std::min(newColSize,colSize_);
  395. for(std::size_t r=0; r<minRowSize; ++r)
  396. for(std::size_t c=0; c<minColSize; ++c)
  397. m[r][c] = data_[r][c];
  398.  
  399. this->swap(m);
  400. }
  401. //------------------------------------------------
  402. template<typename T>
  403. bool Matrix<T>::empty()const
  404. {
  405. return !data_ && !rowSize_ && !colSize_;
  406. }
  407.  
  408. template<typename T>
  409. std::size_t Matrix<T>::rowSize()const
  410. {
  411. return rowSize_;
  412. }
  413.  
  414. template<typename T>
  415. std::size_t Matrix<T>::colSize()const
  416. {
  417. return colSize_;
  418. }
  419.  
  420. template<typename T>
  421. bool Matrix<T>::isSquare() const
  422. {
  423. return rowSize_==colSize_;
  424. }
  425.  
  426. template<typename T>
  427. Row<T>& Matrix<T>::operator[](std::size_t r)
  428. {
  429. return data_[r];
  430. }
  431.  
  432. template<typename T>
  433. const Row<T>& Matrix<T>::operator[](std::size_t r)const
  434. {
  435. return data_[r];
  436. }
  437.  
  438. template<typename T>
  439. bool Matrix<T>::operator==(const Matrix &m) const
  440. {
  441. if(rowSize_==m.rowSize_ && colSize_==m.colSize_)
  442. {
  443. for(std::size_t r=0; r<rowSize_; ++r)
  444. for(std::size_t c=0; c<colSize_; ++c)
  445. if(data_[r][c]!=m.data_[r][c])
  446. return false;
  447. return true;
  448. }
  449. return false;
  450. }
  451. //------------------------------------------------
  452. template<typename T>
  453. void Matrix<T>::fill(const T& value)
  454. {
  455. for(std::size_t r=0; r<rowSize_; ++r)
  456. for(std::size_t c=0; c<colSize_; ++c)
  457. data_[r][c]= value;
  458. }
  459. //------------------------------------------------
  460. template<typename T>
  461. Matrix<T> Matrix<T>::operator+(const Matrix<T>& m)const
  462. {
  463. assert(rowSize_== m.rowSize_ && colSize_== m.colSize_);
  464.  
  465. Matrix<T> rm(rowSize_,colSize_);
  466. for(std::size_t r=0; r<rowSize_; ++r)
  467. for(std::size_t c=0; c<colSize_; ++c)
  468. rm.data_[r][c]= data_[r][c]+m.data_[r][c];
  469. return rm;
  470. }
  471.  
  472. template<typename T>
  473. Matrix<T> Matrix<T>::operator-(const Matrix<T>& m)const
  474. {
  475. assert(rowSize_== m.rowSize_ && colSize_== m.colSize_);
  476.  
  477. Matrix<T> rm(rowSize_,colSize_);
  478. for(std::size_t r=0; r<rowSize_; ++r)
  479. for(std::size_t c=0; c<colSize_; ++c)
  480. rm.data_[r][c]= data_[r][c]-m.data_[r][c];
  481. return rm;
  482. }
  483.  
  484. template<typename T>
  485. Matrix<T> Matrix<T>::operator!() const
  486. {
  487. return inversed();
  488. }
  489.  
  490. template<typename T>
  491. Matrix<T> Matrix<T>::operator~() const
  492. {
  493. return transponded();
  494. }
  495. //------------------------------------------------
  496. template<typename T>
  497. std::ostream& operator<<(std::ostream& stream,const Matrix<T>& m)
  498. {
  499. for(std::size_t r=0;r< m.rowSize_; ++r)
  500. {
  501. if(r)
  502. stream<<std::endl;
  503. for(std::size_t c=0;c< m.colSize_; ++c)
  504. {
  505. if(c==0) stream<< m[r][c];
  506. else stream<<"\t"<< m[r][c];
  507. }
  508. }
  509. return stream;
  510. }
  511.  
  512. template<typename T>
  513. std::istream& operator>>(std::istream& stream,Matrix<T>& m)
  514. {
  515. std::vector<std::vector<T> > rows;
  516. std::string line;
  517.  
  518. std::size_t colSize= 0;
  519.  
  520. while(getline(stream,line))
  521. {
  522. std::stringstream ss(line);
  523. std::vector<T> row;
  524. T value;
  525. while(ss>>value)
  526. row.push_back(value);
  527.  
  528. if(colSize==0)
  529. colSize= row.size();
  530. else if(colSize!=row.size())
  531. {
  532. stream.setstate(std::ios::failbit);
  533. return stream;
  534. }
  535. rows.push_back(row);
  536. }
  537.  
  538. m.resize(rows.size(),colSize);
  539. for(std::size_t r=0; r<rows.size(); ++r)
  540. for(std::size_t c=0;c<rows[r].size(); ++c)
  541. m.data_[r][c]= rows[r][c];
  542.  
  543. return stream;
  544. }
  545. //------------------------------------------------
  546. template<typename T>
  547. Matrix<T> operator*(const Matrix<T>& m,const T& value)
  548. {
  549. Matrix<T> rm(m.rowSize_,m.colSize_);
  550. for(std::size_t r=0; r<m.rowSize_; ++r)
  551. for(std::size_t c=0; c<m.colSize_; ++c)
  552. rm.data_[r][c]= m.data_[r][c]*value;
  553. return rm;
  554. }
  555.  
  556. template<typename T>
  557. Matrix<T> operator/(const Matrix<T>& m,const T& value)
  558. {
  559. Matrix<T> rm(m.rowSize_,m.colSize_);
  560. for(std::size_t r=0; r<m.rowSize_; ++r)
  561. for(std::size_t c=0; c<m.colSize_; ++c)
  562. rm.data_[r][c]= m.data_[r][c]/value;
  563. return rm;
  564. }
  565.  
  566. template<typename T>
  567. Matrix<T> operator*(const T& value,const Matrix<T>& m)
  568. {
  569. Matrix<T> rm(m.rowSize_,m.colSize_);
  570. for(std::size_t r=0; r<m.rowSize_; ++r)
  571. for(std::size_t c=0; c<m.colSize_; ++c)
  572. rm.data_[r][c]= value*m.data_[r][c];
  573. return rm;
  574. }
  575.  
  576. template<typename T>
  577. Matrix<T> operator/(const T& value,const Matrix<T>& m)
  578. {
  579. Matrix<T> rm(m.rowSize_,m.colSize_);
  580. for(std::size_t r=0; r<m.rowSize_; ++r)
  581. for(std::size_t c=0; c<m.colSize_; ++c)
  582. rm.data_[r][c]= value/m.data_[r][c];
  583. return rm;
  584. }
  585. //------------------------------------------------
  586. template<typename T>
  587. bool Matrix<T>::canMultiply(const Matrix<T>& m)const
  588. {
  589. return colSize_== m.rowSize_;
  590. }
  591.  
  592. template<typename T>
  593. Matrix<T> Matrix<T>::operator*(const Matrix<T>& m)const
  594. {
  595. Matrix<T> rm;
  596. if(!canMultiply(m))
  597. throw std::runtime_error("Can not multiply this matrix");
  598.  
  599. rm.resize(rowSize_,m.colSize_);
  600. rm.fill(T(0));
  601.  
  602. for(std::size_t r=0; r<rm.rowSize(); ++r)
  603. for(std::size_t c=0; c<rm.colSize(); ++c)
  604. {
  605. for(std::size_t i=0; i<colSize_; ++i)
  606. rm[r][c]+= data_[r][i]*m.data_[i][c];
  607. }
  608. return rm;
  609. }
  610. //------------------------------------------------
  611. template<typename T>
  612. T& Matrix<T>::item(int row,int col)
  613. {
  614. row%= (int)rowSize_;
  615. col%= (int)colSize_;
  616.  
  617. row= (row>=0)?row:(row+rowSize_);
  618. col= (col>=0)?col:(col+colSize_);
  619.  
  620. return data_[row][col];
  621. }
  622.  
  623. template<typename T>
  624. const T& Matrix<T>::item(int row, int col)const
  625. {
  626. row%= (int)rowSize_;
  627. col%= (int)colSize_;
  628.  
  629. row= (row>=0)?row:(row+rowSize_);
  630. col= (col>=0)?col:(col+colSize_);
  631.  
  632. return data_[row][col];
  633. }
  634. //------------------------------------------------
  635. template<typename T>
  636. T Matrix<T>::det()const
  637. {
  638. if(!isSquare())
  639. throw std::runtime_error("Matrix is not square!");
  640.  
  641. if(colSize_==2)
  642. return data_[0][0]*data_[1][1]-data_[1][0]*data_[0][1];
  643.  
  644. T d(0);
  645. for(std::size_t c=0; c<colSize_; ++c)
  646. {
  647. T p(1),n(1);
  648. for(std::size_t i=0; i<rowSize_; ++i)
  649. {
  650. p*= item(c+i,i);
  651. n*= item(int(rowSize_)-1-c-i,i);
  652. }
  653. d+= p-n;
  654. }
  655. return d;
  656. }
  657. //------------------------------------------------
  658. template<typename T>
  659. Matrix<T> Matrix<T>::minor(std::size_t row,std::size_t col)const
  660. {
  661. if(empty())
  662. throw std::runtime_error("Matrix is empty!");
  663.  
  664. Matrix<T> rm(rowSize_-1,colSize_-1);
  665. for(std::size_t r1=0,r2=0; r1<rowSize_; ++r1)
  666. {
  667. if(r1!=row)
  668. {
  669. for(std::size_t c1=0,c2=0; c1<colSize_; ++c1)
  670. if(c1!=col)
  671. {
  672. rm.data_[r2][c2]= data_[r1][c1];
  673. ++c2;
  674. }
  675. ++r2;
  676. }
  677. }
  678. return rm;
  679. }
  680.  
  681. template<typename T>
  682. T Matrix<T>::minor_det(std::size_t row,std::size_t col) const
  683. {
  684. return minor(row,col).det();
  685. }
  686.  
  687. template<typename T>
  688. T Matrix<T>::addition(std::size_t row,std::size_t col)const
  689. {
  690. int k= (row+col)%2?-1:+1;
  691. return k*minor_det(row,col);
  692. }
  693.  
  694. //------------------------------------------------
  695. template<typename T>
  696. Matrix<T> Matrix<T>::inversed()const
  697. {
  698. if(!isSquare())
  699. throw std::runtime_error("Matrix is not square!");
  700.  
  701. Matrix<T> rm(rowSize_,colSize_);
  702. T d= det();
  703. if(d==0)
  704. throw std::runtime_error("det Matrix is zero!");
  705.  
  706. for(std::size_t r=0; r<rowSize_; ++r)
  707. for(std::size_t c=0; c<colSize_; ++c)
  708. {
  709. rm.data_[c][r]= addition(r,c)/d;
  710. }
  711. return rm;
  712. }
  713.  
  714. template<typename T>
  715. void Matrix<T>::inverse()
  716. {
  717. if(!isSquare())
  718. throw std::runtime_error("Matrix is not square!");
  719.  
  720. Matrix<T> rm(rowSize_,colSize_);
  721. T d= det();
  722. if(d==0)
  723. throw std::runtime_error("det Matrix is zero!");
  724.  
  725. for(std::size_t r=0; r<rowSize_; ++r)
  726. for(std::size_t c=0; c<colSize_; ++c)
  727. {
  728. rm.data_[c][r]= addition(r,c)/d;
  729. }
  730.  
  731. rm.swap(rm);
  732. }
  733.  
  734.  
  735. template<typename T>
  736. Matrix<T> Matrix<T>::transponded()const
  737. {
  738. Matrix<T> rm(colSize_,rowSize_);
  739. for(std::size_t r=0; r<rowSize_; ++r)
  740. for(std::size_t c=0; c<colSize_; ++c)
  741. rm.data_[c][r]= data_[r][c];
  742. return rm;
  743. }
  744.  
  745. template<typename T>
  746. void Matrix<T>::transponde()
  747. {
  748. if(!isSquare())
  749. {
  750. swap(transponded());
  751. return;
  752. }
  753.  
  754. for(std::size_t i=0; i<rowSize_; ++i)
  755. {
  756. for(std::size_t c=i+1; c<colSize_; ++c)
  757. std::swap(data_[c][i],data_[i][c]);
  758. }
  759. }
  760.  
  761.  
  762. int main()
  763. {
  764. std::srand(std::time(0));
  765. Matrix<int> m(50,50);
  766. for(int c=0; c<m.colSize(); ++c)
  767. for(int r=0; r<m.rowSize(); ++r)
  768. m[r][c]= std::rand()%10+1;
  769.  
  770. int d = m.det();
  771. std::cout<< d;
  772.  
  773. return 0;
  774. }
Success #stdin #stdout 0s 4528KB
stdin
Standard input is empty
stdout
-134217728