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

          Line data    Source code
       1             : /* 
       2             :  * File:   SeparableSum.cpp
       3             :  * Author: Pantelis Sopasakis
       4             :  * 
       5             :  * Created on October 30, 2015, 7:22 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 "SeparableSum.h"
      22             : #include <iostream>
      23             : 
      24             : /**
      25             :  * Constructs the sub-vector \c c_x which is defined by a given set of indexes.
      26             :  * 
      27             :  * @param c_idx set of indexes
      28             :  * @param x original vector x
      29             :  * @param c_x sub-vector
      30             :  */
      31             : void prepare_cx(std::vector<size_t> * c_idx, const Matrix& x, Matrix * c_x);
      32             : 
      33           8 : SeparableSum::~SeparableSum() {
      34           8 : }
      35             : 
      36           4 : SeparableSum::SeparableSum(std::map<Function*, std::vector<size_t>*> fun_idx_map) :
      37           4 : Function(), m_fun_idx_map(fun_idx_map) {
      38           4 : }
      39             : 
      40        1096 : void prepare_cx(std::vector<size_t> * c_idx, const Matrix& x, Matrix * c_x) {
      41        1096 :     size_t k = 0;
      42        8883 :     for (std::vector<size_t>::iterator idx_iterator = c_idx->begin();
      43        5922 :             idx_iterator != c_idx->end();
      44             :             ++idx_iterator) {
      45        1865 :         c_x -> set(k, 0, x.get(*idx_iterator, 0));
      46        1865 :         k++;
      47             :     }
      48        1096 : }
      49             : 
      50           1 : int SeparableSum::call(Matrix& x, double& f) {
      51             :     //LCOV_EXCL_START
      52             :     if (!x.isColumnVector()) throw std::invalid_argument("x must be a column-vector");
      53             :     //LCOV_EXCL_STOP
      54             : 
      55             :     /* sub-matrix */
      56           1 :     Matrix *c_x = NULL;
      57             : 
      58             :     /* initialization of result f(x) */
      59           1 :     f = 0.0;
      60             : 
      61             : 
      62             :     /* Invoke all functions */
      63           9 :     for (std::map<Function*, std::vector<size_t> * >::iterator map_iterator = m_fun_idx_map.begin()
      64           6 :             ; map_iterator != m_fun_idx_map.end()
      65             :             ; ++map_iterator) {
      66             :         /* current vector of indices*/
      67           2 :         std::vector<size_t> * c_idx = NULL;
      68             : 
      69             :         /* temporary value of sub-invocations */
      70             :         double f_temp;
      71             : 
      72             :         /* status of sub-invocations   */
      73             :         int status;
      74             : 
      75             :         /* Pointer to current function */
      76           2 :         Function * c_fun = NULL;
      77           2 :         c_fun = map_iterator->first;
      78             : 
      79             :         /* Function indices         */
      80           2 :         c_idx = map_iterator->second;
      81             : 
      82             :         /* initialize new sub-matrix */
      83           2 :         c_x = new Matrix(c_idx->size(), 1);
      84             : 
      85             :         /* iterator for the indices of c_fun */
      86           2 :         prepare_cx(c_idx, x, c_x);
      87             : 
      88             :         /* invoke sub-function on c_x, return f_temp */
      89           2 :         status = c_fun -> call(*c_x, f_temp);
      90             :         //LCOV_EXCL_START
      91             :         if (ForBESUtils::STATUS_OK != status) {
      92             :             delete c_x;
      93             :             c_x = NULL;
      94             :             return status;
      95             :         }
      96             :         //LCOV_EXCL_STOP
      97           2 :         f += f_temp;
      98             :     }
      99             : 
     100           1 :     if (c_x != NULL) {
     101           1 :         delete c_x;
     102           1 :         c_x = NULL;
     103             :     }
     104           1 :     return ForBESUtils::STATUS_OK;
     105             : }
     106             : 
     107         350 : int SeparableSum::call(Matrix& x, double& f, Matrix& grad) {
     108         350 :     Matrix *c_x = NULL;
     109         350 :     f = 0.0;
     110         350 :     Matrix *c_grad = NULL;
     111             :     /* Invoke all functions */
     112        4200 :     for (std::map<Function*, std::vector<size_t> * >::iterator map_iterator = m_fun_idx_map.begin()
     113        2800 :             ; map_iterator != m_fun_idx_map.end()
     114             :             ; ++map_iterator) {
     115        1050 :         std::vector<size_t> * c_idx = NULL;
     116             :         double f_temp;
     117             :         int status;
     118        1050 :         Function * c_fun = NULL;
     119        1050 :         c_fun = map_iterator->first;
     120        1050 :         c_idx = map_iterator->second;
     121        1050 :         c_x = new Matrix(c_idx->size(), 1);
     122        1050 :         prepare_cx(c_idx, x, c_x);
     123        1050 :         c_grad = new Matrix(c_idx->size(), 1);
     124        1050 :         status = c_fun -> call(*c_x, f_temp, *c_grad);
     125             : 
     126             :         //LCOV_EXCL_START
     127             :         if (!ForBESUtils::is_status_ok(status)) {
     128             :             delete c_x;
     129             :             c_x = NULL;
     130             :             delete c_grad;
     131             :             c_grad = NULL;
     132             :             return status;
     133             :         }
     134             :         //LCOV_EXCL_STOP
     135             : 
     136        1050 :         size_t k = 0;
     137        1050 :         std::vector<size_t>::iterator idx_iterator;
     138        2800 :         for (idx_iterator = c_idx->begin(); idx_iterator != c_idx->end(); ++idx_iterator) {
     139        1750 :             grad[*idx_iterator] = c_grad->get(k);
     140        1750 :             k++;
     141             :         }
     142             : 
     143        1050 :         f += f_temp;
     144             :     }
     145             : 
     146         350 :     if (c_x != NULL) {
     147         350 :         delete c_x;
     148         350 :         c_x = NULL;
     149             :     }
     150         350 :     if (c_grad != NULL) {
     151         350 :         delete c_grad;
     152         350 :         c_grad = NULL;
     153             :     }
     154         350 :     return ForBESUtils::STATUS_OK;
     155             : }
     156             : 
     157           1 : int SeparableSum::callProx(Matrix& x, double gamma, Matrix& prox) {
     158             :     //LCOV_EXCL_START
     159             :     if (!x.isColumnVector()) {
     160             :         throw std::invalid_argument("x must be a column-vector");
     161             :     }
     162             :     //LCOV_EXCL_STOP
     163             : 
     164           1 :     Matrix *c_x = NULL;
     165           1 :     Matrix *c_prox = NULL;
     166             : 
     167           9 :     for (std::map<Function*, std::vector<size_t> * >::iterator map_iterator = m_fun_idx_map.begin()
     168           6 :             ; map_iterator != m_fun_idx_map.end()
     169             :             ; ++map_iterator) {
     170           2 :         Function * c_fun = map_iterator->first;
     171           2 :         std::vector<size_t> * c_idx = map_iterator->second;
     172           2 :         c_x = new Matrix(c_idx->size(), 1);
     173           2 :         prepare_cx(c_idx, x, c_x);
     174             : 
     175           2 :         c_prox = new Matrix(c_idx->size(), 1);
     176           2 :         int status = c_fun -> callProx(*c_x, gamma, *c_prox);
     177             :         //LCOV_EXCL_START
     178             :         if (!ForBESUtils::is_status_ok(status)) {
     179             :             delete c_x;
     180             :             delete c_prox;
     181             :             return status;
     182             :         }
     183             :         //LCOV_EXCL_STOP
     184           2 :         size_t k = 0;
     185           2 :         std::vector<size_t>::iterator idx_iterator;
     186           7 :         for (idx_iterator = c_idx->begin(); idx_iterator != c_idx->end(); ++idx_iterator) {
     187           5 :             prox[*idx_iterator] = c_prox->get(k);
     188           5 :             k++;
     189             :         }
     190             :     }
     191           1 :     if (c_x != NULL) delete c_x;
     192           1 :     if (c_prox != NULL) delete c_prox;
     193           1 :     return ForBESUtils::STATUS_OK;
     194             : }
     195             : 
     196           1 : int SeparableSum::callProx(Matrix& x, double gamma, Matrix& prox, double& f_at_prox) {
     197             :     //LCOV_EXCL_START
     198             :     if (!x.isColumnVector()) {
     199             :         throw std::invalid_argument("x must be a column-vector");
     200             :     }
     201             :     //LCOV_EXCL_STOP
     202             : 
     203           1 :     Matrix *c_x = NULL;
     204           1 :     Matrix *c_prox = NULL;
     205             : 
     206           1 :     f_at_prox = 0.0;
     207           1 :     double f_at_prox_temp = 0.0;
     208           9 :     for (std::map<Function*, std::vector<size_t> * >::iterator map_iterator = m_fun_idx_map.begin()
     209           6 :             ; map_iterator != m_fun_idx_map.end()
     210             :             ; ++map_iterator) {
     211           2 :         Function * c_fun = map_iterator->first;
     212           2 :         std::vector<size_t> * c_idx = map_iterator->second;
     213           2 :         c_x = new Matrix(c_idx->size(), 1);
     214           2 :         prepare_cx(c_idx, x, c_x);
     215             : 
     216           2 :         c_prox = new Matrix(c_idx->size(), 1);
     217           2 :         int status = c_fun -> callProx(*c_x, gamma, *c_prox, f_at_prox_temp);
     218           2 :         f_at_prox += f_at_prox_temp;
     219             : 
     220             :         //LCOV_EXCL_START
     221             :         if (ForBESUtils::STATUS_OK != status) {
     222             :             delete c_x;
     223             :             delete c_prox;
     224             :             return status;
     225             :         }
     226             :         //LCOV_EXCL_STOP
     227             : 
     228           2 :         size_t k = 0;
     229           2 :         std::vector<size_t>::iterator idx_iterator;
     230           7 :         for (idx_iterator = c_idx->begin(); idx_iterator != c_idx->end(); ++idx_iterator) {
     231           5 :             prox[*idx_iterator] = c_prox->get(k);
     232           5 :             k++;
     233             :         }
     234             :     }
     235           1 :     if (c_x != NULL) delete c_x;
     236           1 :     if (c_prox != NULL) delete c_prox;
     237           1 :     return ForBESUtils::STATUS_OK;
     238             : }
     239             : 
     240          20 : int SeparableSum::callConj(Matrix& x, double& f_star) {
     241             :     //LCOV_EXCL_START
     242             :     if (!x.isColumnVector()) {
     243             :         throw std::invalid_argument("x must be a column-vector");
     244             :     }
     245             :     //LCOV_EXCL_STOP
     246          20 :     f_star = 0.0;
     247             : 
     248          20 :     std::map<Function*, std::vector<size_t> * >::iterator map_iterator;
     249          20 :     Function * c_fun = NULL;
     250          20 :     Matrix *c_x = NULL;
     251             : 
     252          60 :     for (map_iterator = m_fun_idx_map.begin(); map_iterator != m_fun_idx_map.end(); ++map_iterator) {
     253          40 :         std::vector<size_t> * c_idx = NULL;
     254          40 :         c_fun = map_iterator->first; // current function
     255          40 :         c_idx = map_iterator->second; // current index set I
     256          40 :         c_x = new Matrix(c_idx->size(), 1); // prepare current vector
     257          40 :         prepare_cx(c_idx, x, c_x);
     258             : 
     259             :         double f_star_temp;
     260          40 :         int status = c_fun -> callConj(*c_x, f_star_temp);
     261             :         //LCOV_EXCL_START
     262             :         if (!ForBESUtils::is_status_ok(status)) {
     263             :             delete c_x;
     264             :             c_x = NULL;
     265             :             return status;
     266             :         }
     267             :         //LCOV_EXCL_STOP
     268          40 :         f_star += f_star_temp;
     269             :     }
     270          20 :     if (c_x != NULL) {
     271          20 :         delete c_x;
     272          20 :         c_x = NULL;
     273             :     }
     274          20 :     return ForBESUtils::STATUS_UNDEFINED_FUNCTION;
     275             : }
     276             : 
     277           2 : FunctionOntologicalClass SeparableSum::category() {
     278           2 :     FunctionOntologicalClass meta("SeparableSum");
     279           2 :     meta.set_defines_f(true);
     280           2 :     meta.set_defines_grad(true);
     281           2 :     meta.set_defines_prox(true);
     282           2 :     meta.set_defines_conjugate(true);
     283           2 :     meta.add_superclass(FunctionOntologyRegistry::function());
     284           2 :     return meta;
     285           3 : }
     286             : 
     287             : 

Generated by: LCOV version 1.10