/** *Overloading the '*' operator. Only works when matrix a's columns are equal to matrix b's *rows, otherwise there is a size error. *Returns a new matrix equal to a * b * */ SMatrix operator*(const SMatrix& a, const SMatrix& b) throw(MatrixError) { if(a.cols() != b.rows()) { //Check whether a's columns are equal to b's rows throw MatrixError("Matrix size error"); //if not throw size error } SMatrix c(a.rows(),b.cols()); //dimensions of new matrix for(auto it = a.ridx_.cbegin();it != a.ridx_.cend();++it) { //Loop through a's rows int row = it->first; int nElements = it->second.first + it->second.second; for(SMatrix::size_type i = 0; i < b.cols(); ++i) { //Loop through b's columns int col = i; int val = 0; for(int pos = it->second.first; pos < nElements; ++pos) { //Loop through a's columns val += a.vals_[pos] * b(a.cidx_[pos],i); //adding the multiplications to } //val if(val != 0) { c.setVal(row,col,val); } } } return c; }
/** *Overloading the '!=' operator. *Returns a bool value whether the matrices are not equal * */ bool operator!=(const SMatrix& a, const SMatrix& b) { bool notEqual = false; if(a.rows() != b.rows() || a.cols() != b.cols()) { //If the matrices have different notEqual = true; //dimensions } else { b.begin(); for(a.begin(); !a.end() && !notEqual; a.next()) { //Compare all values of a to b until if(a.value() != b.value()) { //not matching values are notEqual = true; //found } b.next(); } } return notEqual; }
/** *Overloading the '==' operator. *Returns a bool value whether the matrices are equal * */ bool operator==(const SMatrix& a, const SMatrix& b) { bool equal = true; if(a.rows() != b.rows() || a.cols() != b.cols()) { //If the matrices do not have the equal = false; //same dimensions } else { b.begin(); for(a.begin(); !a.end(); a.next()) { //compare all the values of a to b if(a.value() != b.value()) { equal = false; } b.next(); } } return equal; }
/** *Overloading the '-' operator. Only works when both matrices have equal dimensions *Returns a new matrix equal to a - b * */ SMatrix operator-(const SMatrix& a, const SMatrix& b) throw(MatrixError) { if(a.cols() != b.cols() || a.rows() != b.rows()) { //Check whether or not dimensions are equal throw MatrixError("Matrix size error"); //if not throw size error } SMatrix c(a.rows(),a.cols()); //dimensions of new matrix b.begin(); for(a.begin(); !a.end(); a.next()) { //Loop through all values of a and b, and subtract int val = a.value() - b.value(); c.setVal(a.rowPointer_,a.colPointer_,val); //add new subtraction to new matrix b.next(); } return c; }
/** *Transpose method, that transposes a matrix. *Returns a new matrix equal to the transpose of a. */ SMatrix transpose(const SMatrix& a) { SMatrix c(a.rows(),a.cols()); for(auto it = a.ridx_.cbegin();it != a.ridx_.cend();++it) { //Loop through a's rows int row = it->first; int nElements = it->second.first + it->second.second; for(int pos = it->second.first; pos < nElements; ++pos) { //Loop through a's columns c.setVal(a.cidx_[pos],row,a.vals_[pos]); //add value to new matrix } //with rows and columns swapped } return c; }
int main(int argc, char** argv) { if (argc != 5) { std::cerr << "usage: " << argv[0] << " <dimension>" << " <# of non-zero values in each row>" << " <# of eigenvectors>" << " <type of eigenvalues>" << std::endl; std::cerr << "\ttype of eigenvalues: LA SA BE LM SM" << std::endl; return 1; } const int n = std::atoi(argv[1]), k = std::atoi(argv[2]), r = std::atoi(argv[3]); const arpaca::EigenvalueType type = GetEigenvalueType(argv[4]); std::cerr << "Making matrix" << std::endl; std::mt19937 generator(42); SMatrix X = MakeSparseSymmetricRandomMatrix(n, k, generator); std::cerr << "Start performance test" << std::endl; chrono::steady_clock::time_point begin = chrono::steady_clock::now(); arpaca::SymmetricEigenSolver<double> solver = arpaca::Solve(X, r, type); chrono::steady_clock::time_point end = chrono::steady_clock::now(); chrono::duration<double> duration_ = chrono::duration_cast<chrono::duration<double>>(end - begin); const double duration = duration_.count(); std::cout << " DIMENSION: " << X.rows() << std::endl; std::cout << " NONZEROS: " << X.nonZeros() << std::endl; std::cout << " DURATION: " << duration << " SEC." << std::endl; std::cout << " ITER: " << solver.num_actual_iterations() << std::endl; std::cout << "CONVERGED EIGVALS: " << solver.num_converged_eigenvalues() << std::endl; std::cout << " INFO: " << solver.GetInfo() << std::endl; }