LCOV - code coverage report
Current view: top level - source - IndSOC.cpp (source / functions) Hit Total Coverage
Test: LibForBES Unit Tests Lines: 44 48 91.7 %
Date: 2016-04-18 Functions: 8 9 88.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * File:   IndSOC.cpp
       3             :  * Author: Lorenzo Stella
       4             :  *
       5             :  * Created on September 21, 2015, 11:08 AM
       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 "IndSOC.h"
      22             : 
      23           2 : IndSOC::IndSOC(int n) : Function() {
      24           2 :     this->m_n = n;
      25           2 : }
      26             : 
      27           4 : IndSOC::~IndSOC() {
      28           4 : }
      29             : 
      30           3 : int IndSOC::call(Matrix& x, double& f) {
      31           3 :     if (!x.isColumnVector()) {
      32           0 :         throw std::invalid_argument("x must be a vector");
      33             :     }
      34           3 :     volatile bool isInside = true;
      35           3 :     volatile size_t i = 0;
      36           3 :     size_t n = x.getNrows();
      37           3 :     double squaredNorm = 0;
      38           3 :     double t = x[n - 1];
      39             : 
      40          18 :     while (i < n - 1 && isInside) {
      41             :         double xi;
      42          12 :         xi = x[i];
      43          12 :         squaredNorm += xi*xi;
      44          12 :         i++;
      45             :     }
      46           3 :     f = (t >= sqrt(squaredNorm)) ? 0.0 : INFINITY;
      47           3 :     return ForBESUtils::STATUS_OK;
      48             : }
      49             : 
      50           0 : int IndSOC::callProx(Matrix& x, double gamma, Matrix& prox) {
      51             :     double f_at_prox;
      52           0 :     return callProx(x, gamma, prox, f_at_prox);
      53             : }
      54             : 
      55           3 : int IndSOC::callProx(Matrix& x, double gamma, Matrix& prox, double& f_at_prox) {
      56           3 :     f_at_prox = 0.0;
      57           3 :     if (!x.isColumnVector()) {
      58           0 :         throw std::invalid_argument("x must be a vector");
      59             :     }
      60           3 :     size_t i = 0;
      61           3 :     size_t n = x.getNrows();
      62           3 :     double norm = 0, xi, scal;
      63           3 :     double t = x[n-1];
      64             : 
      65          18 :     while (i < n - 1) {
      66          12 :         xi = x[i];
      67          12 :         norm += xi*xi;
      68          12 :         i++;
      69             :     }
      70             : 
      71           3 :     norm = sqrt(norm);
      72             : 
      73           3 :     if (t > norm) {
      74           1 :         prox = Matrix(x); // prox = x
      75           2 :     } else if (t < -norm) { // prox = zero vector
      76           6 :         for (size_t j = 0; j < n; j++) {
      77           5 :             prox[j] = 0.0;
      78             :         }
      79             :     } else {
      80             :         /* perform actual projection here */
      81           1 :         scal = (1 + t / norm) / 2;
      82           5 :         for (size_t j = 0; j < n - 1; j++) {
      83           4 :             xi = x[j];
      84           4 :             prox[j] = scal * xi;
      85             :         }
      86           1 :         prox[n - 1] = (norm + t) / 2.0;
      87             :     }
      88           3 :     return ForBESUtils::STATUS_OK;
      89             : }
      90             : 
      91           2 : FunctionOntologicalClass IndSOC::category() {
      92           2 :     return FunctionOntologyRegistry::indicator();
      93           3 : }

Generated by: LCOV version 1.10