LCOV - code coverage report
Current view: top level - src - gensvm_zv.c (source / functions) Hit Total Coverage
Test: coverage.all Lines: 27 27 100.0 %
Date: 2017-02-21 18:44:20 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /**
       2             :  * @file gensvm_zv.c
       3             :  * @author G.J.J. van den Burg
       4             :  * @date 2016-10-17
       5             :  * @brief Functions for computing the ZV matrix product
       6             :  *
       7             :  * @details
       8             :  * This file exists because the product Z*V of two matrices occurs both in the
       9             :  * computation of the loss function and for predicting class labels. Moreover,
      10             :  * a distinction has to be made between dense Z matrices and sparse Z
      11             :  * matrices, hence a seperate file is warranted.
      12             :  *
      13             :  * @copyright
      14             :  Copyright 2016, G.J.J. van den Burg.
      15             : 
      16             :  This file is part of GenSVM.
      17             : 
      18             :  GenSVM is free software: you can redistribute it and/or modify
      19             :  it under the terms of the GNU General Public License as published by
      20             :  the Free Software Foundation, either version 3 of the License, or
      21             :  (at your option) any later version.
      22             : 
      23             :  GenSVM is distributed in the hope that it will be useful,
      24             :  but WITHOUT ANY WARRANTY; without even the implied warranty of
      25             :  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      26             :  GNU General Public License for more details.
      27             : 
      28             :  You should have received a copy of the GNU General Public License
      29             :  along with GenSVM. If not, see <http://www.gnu.org/licenses/>.
      30             : 
      31             :  */
      32             : 
      33             : #include "gensvm_zv.h"
      34             : 
      35             : /**
      36             :  * @brief Wrapper around sparse/dense versions of this function
      37             :  *
      38             :  * @details
      39             :  * This function tests if the data is stored in dense format or sparse format
      40             :  * by testing if GenData::Z is NULL or not, and calls the corresponding
      41             :  * version of this function accordingly.
      42             :  *
      43             :  * @sa
      44             :  * gensvm_calculate_ZV_dense(), gensvm_calculate_ZV_sparse()
      45             :  *
      46             :  * @param[in]   model   a GenModel instance holding the model
      47             :  * @param[in]   data    a GenData instance with the data
      48             :  * @param[out]  ZV      a pre-allocated matrix of appropriate dimensions
      49             :  */
      50         478 : void gensvm_calculate_ZV(struct GenModel *model, struct GenData *data,
      51             :                 double *ZV)
      52             : {
      53         478 :         if (data->Z == NULL)
      54           4 :                 gensvm_calculate_ZV_sparse(model, data, ZV);
      55             :         else
      56         474 :                 gensvm_calculate_ZV_dense(model, data, ZV);
      57         478 : }
      58             : 
      59             : /**
      60             :  * @brief Compute the product Z*V for when Z is a sparse matrix
      61             :  *
      62             :  * @details
      63             :  * This is a simple sparse-dense matrix multiplication, which uses 
      64             :  * cblas_daxpy() for each nonzero element of Z, to compute Z*V.
      65             :  *
      66             :  * @param[in]   model   a GenModel instance holding the model
      67             :  * @param[in]   data    a GenData instance with the data
      68             :  * @param[out]  ZV      a pre-allocated matrix of appropriate dimensions
      69             :  */
      70           4 : void gensvm_calculate_ZV_sparse(struct GenModel *model,
      71             :                 struct GenData *data, double *ZV)
      72             : {
      73             :         long i, j, jj, jj_start, jj_end, K,
      74           4 :             n_row = data->spZ->n_row;
      75             :         double z_ij;
      76             : 
      77           4 :         K = model->K;
      78             : 
      79           4 :         long *Zia = data->spZ->ia;
      80           4 :         long *Zja = data->spZ->ja;
      81           4 :         double *vals = data->spZ->values;
      82             : 
      83          35 :         for (i=0; i<n_row; i++) {
      84          31 :                 jj_start = Zia[i];
      85          31 :                 jj_end = Zia[i+1];
      86             : 
      87         143 :                 for (jj=jj_start; jj<jj_end; jj++) {
      88         112 :                         j = Zja[jj];
      89         112 :                         z_ij = vals[jj];
      90             : 
      91         112 :                         cblas_daxpy(K-1, z_ij, &model->V[j*(K-1)], 1,
      92         112 :                                         &ZV[i*(K-1)], 1);
      93             :                 }
      94             :         }
      95           4 : }
      96             : 
      97             : /**
      98             :  * @brief Compute the product Z*V for when Z is a dense matrix
      99             :  *
     100             :  * @details
     101             :  * This function uses cblas_dgemm() to compute the matrix product between Z 
     102             :  * and V.
     103             :  *
     104             :  * @param[in]   model   a GenModel instance holding the model
     105             :  * @param[in]   data    a GenData instance with the data
     106             :  * @param[out]  ZV      a pre-allocated matrix of appropriate dimensions
     107             :  */
     108         474 : void gensvm_calculate_ZV_dense(struct GenModel *model,
     109             :                 struct GenData *data, double *ZV)
     110             : {
     111             :         // use n from data, assume m and K are the same between model and data
     112         474 :         long n = data->n;
     113         474 :         long m = model->m;
     114         474 :         long K = model->K;
     115             : 
     116        1896 :         cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, n, K-1, m+1,
     117        1896 :                         1.0, data->Z, m+1, model->V, K-1, 0, ZV, K-1);
     118         474 : }

Generated by: LCOV version 1.12