MyMat0<T,ROWMAJOR> matMul(MyMat0<T,storagePolicy1> const & m1,MyMat0<T,storagePolicy2> const & m2) { MyMat0<T,ROWMAJOR> res(m1.nrow(),m2.ncol(),0.); for(size_type i=0; i<m1.nrow();++i) for(size_type j=0; j<m2.ncol();++j) for(size_type k=0; k<m2.nrow();++k) res(i,j) += m1(i,k)*m2(k,j); return res; }
MyMat0<T,ROWMAJOR> matMulOpt(MyMat0<T,COLUMNMAJOR> const & m1,MyMat0<T,COLUMNMAJOR> const & m2) { MyMat0<T,ROWMAJOR> res(m1.nrow(),m2.ncol(),0.); std::vector<T> tmp(m1.ncol()); for(size_type i=0; i<m1.nrow();++i) { // Store the i-th row of m1 for (size_type l=0; l<m1.ncol(); ++l) { tmp[l]=m1(i,l); } for(size_type j=0; j<m2.ncol();++j) { size_type column_start = m2.gitIndex(0,j); res(i,j) = std::inner_product(tmp.begin(),tmp.end(),m2.cbegin()+column_start,T(0)); /* for(size_type k=0; k<m2.nrow();++k) { res(i,j) += tmp[k]*m2(k,j); } */ } } return res; }
MyMat0<T,ROWMAJOR> matMulOpt(MyMat0<T,ROWMAJOR> const & m1,MyMat0<T,ROWMAJOR> const & m2) { MyMat0<T,ROWMAJOR> res(m1.nrow(),m2.ncol(),0.); std::vector<T> tmp(m2.nrow()); for(size_type j=0; j<m2.ncol();++j) { // Store the jth column of m2 for (size_type l=0; l<m2.nrow(); ++l) { tmp[l]=m2(l,j); } for(size_type i=0; i<m1.nrow();++i) { size_type row_starts= m1.getIndex(i,0); res(i,j) = std::inner_product(tmp.begin(),tmp.end(),m1.cbegin()+row_starts,T(0)); /* for(size_type k=0; k<m2.nrow();++k) { res(i,j) += m1(i,k)*tmp[k]; } */ } } return res; }
int main() { using namespace LinearAlgebra; // I create two matrices MyMat0<COLUMNMAJOR> a; //MyMat0 a; a.resize(3,4); MyMat0<> b(5,5); b.fillRandom(); std::cout<< "Testing copy constructors and move semantic"<<std::endl; MyMat0<ROWMAJOR> t(a); std::cout<<" This matrix should be equal to a"<<std::endl; t.showMe(); MyMat0<ROWMAJOR> tc(std::move(t)); std::cout<<" This matrix should be also equal to a"<<std::endl; tc.showMe(); std::cout<<" This matrix is now empty"<< std::endl; t.showMe(); t=std::move(tc); std::cout<<" Now it is back"<<std::endl; t.showMe(); std::cout<<" And this is empty"<<std::endl; tc.showMe(); /* SHOW THE ADVANTAGES OF MOVE SEMANTIC */ constexpr unsigned int N=10000; MyMat0<ROWMAJOR> matH=Hilbert(N); std::cout<<" Created a matrix of "<<N*N*8/1000000<<" Mbytes"<<std::endl; // Swap with another matrix. MyMat0<ROWMAJOR> tmp = std::move( matH); matH=std::move(tc); tc=std::move(tmp); }
MyMat0<T,ROWMAJOR> matMulOpt(MyMat0<T,ROWMAJOR> const & m1,MyMat0<T,COLUMNMAJOR> const & m2) { MyMat0<T,ROWMAJOR> res(m1.nrow(),m2.ncol(),0.); for(size_type i=0; i<m1.nrow();++i) { for(size_type j=0; j<m2.ncol();++j) { size_type column_start = m2.getIndex(0,j); size_type row_start = m1.getIndex(i,0); size_type row_end = m1.getIndex(i+1,0); res(i,j) = std::inner_product( m1.cbegin()+row_start, m1.cbegin()+row_end, m2.cbegin()+column_start, T(0)); } } /* for(size_type k=0; k<m2.nrow();++k) res(i,j) += m1(i,k)*m2(k,j); */ return res; }
int main() { using namespace LinearAlgebra; // I create two matrices MyMat0<COLUMNMAJOR> a; //MyMat0 a; a.resize(3,4); MyMat0<> b(5,5); b.fillRandom(); a(0,0)=5; a(1,1)=10; a(2,2)=20; //! file to output the matrix std::ofstream ofile; ofile.open("Matrix.dat"); std::cout<<"Some output is in the file Matrix.dat"<<std::endl; /// I want a certain format and precision ofile.setf(std::ios_base::scientific, std::ios_base::floatfield); ofile.precision(16); std::cout<<"MATRIX a:"<<std::endl; a.showMe(); //On screen (default is cout) std::cout<<"Norm1 ="<<a.norm1()<<std::endl; std::cout<<"NormInf ="<<a.normInf()<<std::endl; std::cout<<"Frob. Norm="<<a.normF()<<std::endl<<std::endl; a.showMe(ofile); //Matrix stored on file std::cout<<"Matrix b"<<std::endl; b.showMe(); b.showMe(ofile); //on file ofile.close();// close file std::vector<double> va(4,1.0); std::vector<double> res(a*va); std::cout<<"result of a*["; for (std::vector<double>::iterator it=va.begin();it<va.end()-1; ++it)std::cout<<*it<<","; std::cout<<*(va.end()-1)<<"]^T ="; std::cout<<"["; for (std::vector<double>::iterator i=res.begin();i<res.end()-1;++i)std::cout<<*i<<", "; std::cout<<*(res.end()-1)<<"]"<<std::endl; std::cout<< "Now testing copy constructors and move semantic"<<std::endl; MyMat0<ROWMAJOR> t(a); std::cout<<" This matrix should be equal to a"<<std::endl; t.showMe(); MyMat0<ROWMAJOR> tc(std::move(t)); std::cout<<" This matrix should be also equal to a"<<std::endl; tc.showMe(); std::cout<<" This matrix is now empty"<<std::endl; t.showMe(); t=std::move(tc); std::cout<<" Now is back"<<std::endl; t.showMe(); std::cout<<" And this is empty"<<std::endl; tc.showMe(); /* SHOW THE ADVANTAGES OF MOVE SEMANTIC */ constexpr unsigned int N=10000; MyMat0<ROWMAJOR> matH=Hilbert(N); std::cout<<" Created a matrix of "<<N*N*8/1000000<<" Mbytes"<<std::endl; // Swap with another matrix. MyMat0<ROWMAJOR> tmp = std::move( matH); matH=std::move(tc); tc=std::move(tmp); }
int main() { using namespace LinearAlgebra; // I create two matrices MyMat0<double,COLUMNMAJOR> a; a.resize(3,4); MyMat0<> b(5,5); b.fillRandom(); a(0,0)=5; a(1,1)=10; a(2,2)=20; //! file to output the matrix std::ofstream ofile; ofile.open("Matrix.dat"); std::cout<<"Some output is in the file Matrix.dat"<<std::endl; /// I want a certain format and precision ofile.setf(std::ios_base::scientific, std::ios_base::floatfield); ofile.precision(16); std::cout<<"MATRIX a:"<<std::endl; a.showMe(); //On screen (default is cout) a.showMe(ofile); //Matrix stored on file std::cout<<"Matrix b"<<std::endl; b.showMe(); b.showMe(ofile); //on file ofile.close();// close file std::vector<double> va(4,1.0); std::vector<double> res(a*va); std::cout<<"result of a*["; for (auto it=va.cbegin();it<va.cend()-1; ++it)std::cout<<*it<<","; std::cout<<*(va.end()-1)<<"]^T ="; std::cout<<"["; for (auto i=res.cbegin();i<res.cend()-1;++i)std::cout<<*i<<", "; std::cout<<*(res.end()-1)<<"]"<<std::endl<<std::endl; std::cout<<"Norm1, NOrmInf and NormF of a: "<<a.norm1()<<" "<<a.normInf()<<" "<<a.normF()<<std::endl; // Creating 2 big matrices //MyMat0<double,COLUMNMAJOR> A(1000,1000); MyMat0<double,ROWMAJOR> A(1000,5000); A.fillRandom(); // MyMat0<double,COLUMNMAJOR> B(1000,1000); MyMat0<double,ROWMAJOR> B(5000,500); B.fillRandom(); Timings::Chrono watch; std::cout<< "Standard Matrix Moltiplication"<<"\n"; watch.start(); auto res1=matMul(A,B); watch.stop(); double t1=watch.wallTime(); std::cout<<watch<<std::endl; std::cout<< "Optimized Matrix Moltiplication"<<"\n"; watch.start(); auto res2=matMulOpt(A,B); watch.stop(); double t2=watch.wallTime(); std::cout<<watch<<std::endl; std::cout<<"Gain: "<<100*(t1-t2)/t1<<"%"<<std::endl; }