LCOV - code coverage report
Current view: top level - source - MatrixFactory.cpp (source / functions) Hit Total Coverage
Test: LibForBES Unit Tests Lines: 98 99 99.0 %
Date: 2016-04-18 Functions: 13 13 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* 
       2             :  * File:   MatrixFactory.cpp
       3             :  * Author: Pantelis Sopasakis
       4             :  * 
       5             :  * Created on July 12, 2015, 7:50 PM
       6             :  * 
       7             :  * ForBES is free software: you can redistribute it and/or modify
       8             :  * it under the terms of the GNU Lesser General Public License as published by
       9             :  * the Free Software Foundation, either version 3 of the License, or
      10             :  * (at your option) any later version.
      11             :  *  
      12             :  * ForBES is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      15             :  * GNU Lesser General Public License for more details.
      16             :  * 
      17             :  * You should have received a copy of the GNU Lesser General Public License
      18             :  * along with ForBES. If not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : #include <set>
      22             : 
      23             : #include "MatrixFactory.h"
      24             : #include "Matrix.h"
      25             : 
      26             : #include <vector>       // std::vector
      27             : #include <algorithm>    // std::random_shuffle
      28             : #include <ctime>        // std::time
      29             : #include <functional>
      30             : 
      31             : #include <cmath>
      32             : #include <sstream>
      33             : 
      34             : typedef std::pair<size_t, size_t> nice_pair;
      35             : 
      36           7 : Matrix MatrixFactory::MakeIdentity(size_t n, double alpha) {
      37           7 :     Matrix mat(n, n, Matrix::MATRIX_DIAGONAL);
      38        1344 :     for (size_t i = 0; i < n; i++) {
      39        1337 :         mat[i] = alpha;
      40             :     }
      41           7 :     return mat;
      42             : }
      43             : 
      44        6661 : Matrix MatrixFactory::MakeRandomSparse(size_t nrows, size_t ncols, size_t nnz, float offset, float scale) {
      45        6661 :     Matrix R = MakeSparse(nrows, ncols, nnz, Matrix::SPARSE_UNSYMMETRIC);
      46       13320 :     std::set<nice_pair> s;
      47        6660 :     nice_pair p;
      48             :     while (true) { // construct pairs
      49      512383 :         p.first = (std::rand() % nrows);
      50      512383 :         p.second = (std::rand() % ncols);
      51      512383 :         s.insert(p);
      52      512383 :         if (s.size() == nnz) {
      53        6660 :             break;
      54             :         }
      55             :     }
      56      365832 :     for (std::set<nice_pair>::iterator it = s.begin(); it != s.end(); ++it) {
      57             :         double rand;
      58      359172 :         rand = offset + (scale * std::rand()) / RAND_MAX;
      59      359172 :         R.set(it->first, it->second, rand);
      60             :     }
      61       13320 :     return R;
      62             : }
      63             : 
      64        6235 : Matrix MatrixFactory::MakeRandomMatrix(size_t nrows, size_t ncols, float offset, float scale, Matrix::MatrixType type) {
      65        6235 :     size_t len = 0;
      66        6235 :     switch (type) {
      67             :         case Matrix::MATRIX_DENSE:
      68        5460 :             len = nrows * ncols;
      69        5460 :             break;
      70             :         case Matrix::MATRIX_LOWERTR:
      71             :         case Matrix::MATRIX_SYMMETRIC:
      72         162 :             len = nrows * (nrows + 1) / 2;
      73         162 :             break;
      74             :         case Matrix::MATRIX_DIAGONAL:
      75         612 :             len = nrows;
      76         612 :             break;
      77             :         case Matrix::MATRIX_SPARSE:
      78           1 :             return MakeRandomSparse(nrows, ncols, std::ceil((nrows * ncols) / 3), offset, scale);
      79             :             break;
      80             :         default:
      81           0 :             throw std::logic_error("unsupported");
      82             :     }
      83        6234 :     Matrix mat(nrows, ncols, type);
      84     1603276 :     for (size_t j = 0; j < len; j++) {
      85     1597042 :         mat[j] = static_cast<double> (offset + (scale * std::rand()) / RAND_MAX);
      86             :     }
      87        6234 :     return mat;
      88             : }
      89             : 
      90        3947 : Matrix MatrixFactory::MakeRandomMatrix(size_t nrows, size_t ncols, float offset, float scale) {
      91        3947 :     return MatrixFactory::MakeRandomMatrix(nrows, ncols, offset, scale, Matrix::MATRIX_DENSE);
      92             : }
      93             : 
      94        6678 : Matrix MatrixFactory::MakeSparse(size_t nrows, size_t ncols, size_t max_nnz, Matrix::SparseMatrixType stype) {
      95        6678 :     if (max_nnz > nrows * ncols) {
      96           1 :         std::ostringstream oss;
      97           1 :         oss << "Matrix " << nrows << "x" << ncols << "(max_size=" << (nrows * ncols)
      98           1 :                 << " cannot allocate " << max_nnz << "non-zeros";
      99           1 :         throw std::invalid_argument(oss.str().c_str());
     100             :     }
     101        6677 :     Matrix matrix(nrows, ncols, Matrix::MATRIX_SPARSE);
     102        6677 :     matrix.m_triplet = cholmod_allocate_triplet(nrows, ncols, max_nnz, stype, CHOLMOD_REAL, Matrix::cholmod_handle());
     103        6677 :     matrix.m_sparseStorageType = Matrix::CHOLMOD_TYPE_TRIPLET;
     104        6677 :     return matrix;
     105             : }
     106             : 
     107           2 : Matrix MatrixFactory::MakeSparseSymmetric(size_t n, size_t max_nnz) {
     108           2 :     return MakeSparse(n, n, max_nnz, Matrix::SPARSE_SYMMETRIC_L);
     109             : }
     110             : 
     111           3 : Matrix MatrixFactory::ReadSparse(FILE* fp) {
     112             :     cholmod_sparse *sp;
     113           3 :     sp = cholmod_read_sparse(fp, Matrix::cholmod_handle());
     114             : 
     115           3 :     Matrix mat(sp->nrow, sp->ncol, Matrix::MATRIX_SPARSE);
     116           3 :     mat.m_sparse = sp;
     117           3 :     mat.m_sparseStorageType = Matrix::CHOLMOD_TYPE_SPARSE;
     118           3 :     mat.m_triplet = cholmod_sparse_to_triplet(sp, Matrix::cholmod_handle());
     119           3 :     return mat;
     120             : }
     121             : 
     122          67 : Matrix MatrixFactory::ShallowMatrix(const Matrix& orig) {
     123          67 :     Matrix mat_shallow = Matrix(true);
     124          67 :     mat_shallow.m_transpose = orig.m_transpose;
     125          67 :     mat_shallow.m_nrows = orig.m_nrows;
     126          67 :     mat_shallow.m_ncols = orig.m_ncols;
     127          67 :     mat_shallow.m_dataLength = orig.m_dataLength;
     128          67 :     mat_shallow.m_delete_data = false;
     129          67 :     mat_shallow.m_data = orig.m_data;
     130          67 :     mat_shallow.m_type = orig.m_type;
     131          67 :     mat_shallow.m_sparseStorageType = orig.m_sparseStorageType;
     132          67 :     mat_shallow.m_dense = orig.m_dense;
     133          67 :     mat_shallow.m_triplet = orig.m_triplet;
     134          67 :     mat_shallow.m_sparse = orig.m_sparse;
     135          67 :     return mat_shallow;
     136             : }
     137             : 
     138         242 : Matrix MatrixFactory::ShallowVector(const Matrix& orig, size_t size, size_t offset) {
     139         242 :     if (orig.getType() != Matrix::MATRIX_DENSE) {
     140           1 :         throw std::invalid_argument("This method can only be applied to dense vectors");
     141             :     }
     142         241 :     if (orig.getNcols() != 1 && orig.getNrows() != 1) {
     143           1 :         throw std::invalid_argument("This method can only be applied to vectors");
     144             :     }
     145         240 :     Matrix v_shallow = Matrix(true);
     146         240 :     v_shallow.m_transpose = orig.m_transpose;
     147         240 :     v_shallow.m_nrows = orig.m_transpose ? 1 : size;
     148         240 :     v_shallow.m_ncols = orig.m_transpose ? size : 1;
     149         240 :     v_shallow.m_dataLength = v_shallow.m_nrows * v_shallow.m_ncols;
     150         240 :     v_shallow.m_delete_data = false;
     151         240 :     v_shallow.m_data = orig.m_data + offset;
     152         240 :     return v_shallow;
     153             : }
     154             : 
     155          10 : Matrix MatrixFactory::ShallowVector(const Matrix& orig, size_t offset) {
     156          10 :     return MatrixFactory::ShallowVector(orig, orig.length() - offset, offset);
     157             : }
     158             : 
     159         167 : Matrix MatrixFactory::ShallowVector(double* data, size_t size, size_t offset) {
     160         167 :     Matrix v_shallow = Matrix(true);
     161         167 :     v_shallow.m_transpose = false;
     162         167 :     v_shallow.m_nrows = size;
     163         167 :     v_shallow.m_ncols = 1;
     164         167 :     v_shallow.m_dataLength = v_shallow.m_nrows;
     165         167 :     v_shallow.m_delete_data = false;
     166         167 :     v_shallow.m_data = data + offset;
     167         167 :     return v_shallow;
     168             : }
     169             : 
     170           3 : Matrix MatrixFactory::ShallowVector() {
     171           3 :     Matrix v_shallow = Matrix(true);
     172           3 :     return v_shallow;
     173             : }
     174             : 
     175          96 : Matrix MatrixFactory::ShallowSubVector(Matrix& A, size_t j) {
     176          96 :     double * data = A.getData();
     177          96 :     data += A.getNrows() * j;
     178          96 :     return MatrixFactory::ShallowVector(data, A.getNrows(), 0);
     179             : }
     180             : 
     181             : 
     182             : 
     183             : 
     184             : 

Generated by: LCOV version 1.10