optimization_utils.h

00001 /* MLPACK 0.2
00002  *
00003  * Copyright (c) 2008, 2009 Alexander Gray,
00004  *                          Garry Boyer,
00005  *                          Ryan Riegel,
00006  *                          Nikolaos Vasiloglou,
00007  *                          Dongryeol Lee,
00008  *                          Chip Mappus, 
00009  *                          Nishant Mehta,
00010  *                          Hua Ouyang,
00011  *                          Parikshit Ram,
00012  *                          Long Tran,
00013  *                          Wee Chin Wong
00014  *
00015  * Copyright (c) 2008, 2009 Georgia Institute of Technology
00016  *
00017  * This program is free software; you can redistribute it and/or
00018  * modify it under the terms of the GNU General Public License as
00019  * published by the Free Software Foundation; either version 2 of the
00020  * License, or (at your option) any later version.
00021  *
00022  * This program is distributed in the hope that it will be useful, but
00023  * WITHOUT ANY WARRANTY; without even the implied warranty of
00024  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00025  * General Public License for more details.
00026  *
00027  * You should have received a copy of the GNU General Public License
00028  * along with this program; if not, write to the Free Software
00029  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00030  * 02110-1301, USA.
00031  */
00032 /*
00033  * =====================================================================================
00034  * 
00035  *       Filename:  optimization_utils.h
00036  * 
00037  *    Description
00038  * 
00039  *        Version:  1.0
00040  *        Created:  03/12/2008 06:29:51 PM EDT
00041  *       Revision:  none
00042  *       Compiler:  gcc
00043  * 
00044  *         Author:  Nikolaos Vasiloglou (NV), nvasil@ieee.org
00045  *        Company:  Georgia Tech Fastlab-ESP Lab
00046  * 
00047  * =====================================================================================
00048  */
00049 
00050 #ifndef OPTIMIZATION_UTILS_H_
00051 #define OPTIMIZATION_UTILS_H_
00052 
00053 #include "fastlib/fastlib.h"
00054 
00055 class OptUtils {
00056  public:
00057   static void RemoveMean(Matrix *data) {
00058     index_t dimension=data->n_rows();
00059     index_t num_of_points=data->n_cols();
00060     Vector mean;
00061     mean.Init(dimension);
00062     mean.SetAll(0);
00063     for(index_t i=0; i<num_of_points; i++){
00064       la::AddTo(dimension, data->GetColumnPtr(i), mean.ptr());
00065     }
00066     la::Scale(-1.0/num_of_points, &mean);
00067     for(index_t i=0; i<num_of_points; i++){
00068       la::AddTo(dimension, mean.ptr(), data->GetColumnPtr(i));
00069     }
00070   }
00071   
00072   static void NonNegativeProjection(Matrix *data) {
00073     double *ptr=data->ptr();
00074     for(index_t i=0; i<(index_t)data->n_elements(); i++) {
00075       if (ptr[i]<0) {
00076         ptr[i]=0;
00077       }
00078     }
00079   }
00080   static void BoundProjection(Matrix *data, double lo, double hi) {
00081     double *ptr=data->ptr();
00082     for(index_t i=0; i<(index_t)data->n_elements(); i++) {
00083       if (ptr[i]>hi) {
00084         ptr[i]=hi;
00085         continue;
00086       }
00087       if (ptr[i]<lo) {
00088         ptr[i]=lo;
00089       }
00090     }
00091   }
00092  
00093  
00094   static success_t SVDTransform(Matrix &input_mat, Matrix *output_mat, 
00095       index_t components_to_keep) {
00096     Matrix temp;
00097     temp.Copy(input_mat);
00098     RemoveMean(&temp);
00099     Vector s;
00100     Matrix U, VT;
00101     success_t success=la::SVDInit(temp, &s, &U, &VT);
00102     if (success==SUCCESS_PASS) {
00103       NOTIFY("PCA successful !! Printing requested %i eigenvalues...",
00104           components_to_keep);
00105       double energy_kept=0;
00106       double total_energy=0;
00107       for(index_t i=0; i<components_to_keep; i++) {
00108        NOTIFY("%lg ", s[i]);
00109         energy_kept+=s[i];
00110       }
00111       printf("\n");
00112       for(index_t i=0; i<s.length(); i++) {
00113         total_energy+=s[i];
00114       }
00115       NOTIFY("Kept %lg%% of the energy", energy_kept*100/total_energy);
00116     }
00117     
00118     Vector s_chopped;
00119     s.MakeSubvector(0, components_to_keep, &s_chopped);
00120 //  Matrix temp_U(components_to_keep, U.components_to_keep);
00121     Matrix temp_VT(components_to_keep, VT.n_cols());
00122     for(index_t i=0; i<temp_VT.n_cols(); i++) {
00123       memcpy(temp_VT.GetColumnPtr(i), 
00124           VT.GetColumnPtr(i), components_to_keep*sizeof(double));  
00125     }
00126    
00127     la::ScaleRows(s_chopped, &temp_VT);
00128     output_mat->Own(&temp_VT);
00129 //    la::MulInit(temp_U, temp_VT, output_mat);
00130     /*
00131     Matrix temp_reconstructed;
00132     Matrix temp_S;
00133     temp_S.Init(input_mat.n_rows(), input_mat.n_rows());
00134     temp_S.SetAll(0.0);
00135     for(index_t i=0; i<components_to_keep; i++) {
00136       temp_S.set(i, i, s[i]);
00137     }
00138     Matrix temp_U;
00139     la::MulInit(U, temp_S, &temp_U);
00140     la::MulInit(temp_U, VT, &temp_reconstructed);
00141     for(index_t i=0; i<output_mat->n_cols(); i++) {
00142       memcpy(output_mat->GetColumnPtr(i), 
00143           temp_reconstructed.GetColumnPtr(i), components_to_keep*sizeof(double));  
00144     }
00145     
00146     double error=0;
00147     for(index_t i=0; i<output_mat->n_rows(); i++) {
00148       for(index_t j=0; j<output_mat->n_cols(); j++) {
00149         error+=math::Sqr(output_mat->get(i,j)-input_mat.get(i,j));
00150       }
00151     }
00152     NOTIFY("Reconstruction error : %lg", error);
00153     */
00154     return success;
00155   }
00156   
00157   static void SparseProjection(Matrix *data, double sparse_factor) {
00158     DEBUG_ASSERT(sparse_factor<=1);
00159     DEBUG_ASSERT(sparse_factor>=0);
00160     index_t dimension=data->n_rows();
00161     ArrayList<index_t> zero_coeff;
00162     zero_coeff.Init();
00163     Vector w_vector;
00164     w_vector.Init(dimension);
00165     Vector v_vector;
00166     v_vector.Init(dimension);  
00167     Vector a_vector;
00168     Vector ones;
00169     ones.Init(dimension);
00170     ones.SetAll(1.0);
00171     // This part of the sparsity constraint function formula can be
00172     // precomputed and it is the same for every iteration
00173     double precomputed_sparse_factor=-sparse_factor*(math::Pow<1,2>(dimension)-1)+
00174           math::Pow<1,2>(dimension);
00175 
00176     for (index_t i=0; i<data->n_cols(); i++) {
00177       double *point=data->GetColumnPtr(i);
00178       double l2_norm=la::LMetric<2>(dimension,
00179          point, point);
00180       double l1_norm=precomputed_sparse_factor*l2_norm;
00181       // (L1-\sum x_i)/dimension
00182       double factor1=l1_norm;
00183       for(index_t j=0; j<dimension; j++) {
00184         factor1-=point[j];
00185       }
00186       factor1/=dimension;
00187       for(index_t j=0; j<dimension; j++) {
00188         v_vector[j]+=factor1;
00189       }
00190       zero_coeff.Clear();
00191       Vector midpoint;
00192       midpoint.Init(dimension);
00193       while(true) {
00194        midpoint.SetAll(l1_norm/(dimension-zero_coeff.size()));
00195         for(index_t j=0; j<zero_coeff.size(); j++) {
00196           midpoint[zero_coeff[j]]=0.0;
00197         }
00198         la::SubOverwrite(midpoint, v_vector, &w_vector);
00199         double w_norm=la::LengthEuclidean(w_vector);
00200         double w_times_v = 2*la::Dot(v_vector, w_vector);
00201         double v_norm_minus_l2=la::LengthEuclidean(v_vector)-l2_norm;
00202         double alpha = (-w_times_v+math::Pow<1,2>(w_times_v*w_times_v
00203             -4*w_norm*v_norm_minus_l2))/(2*w_norm);
00204         la::AddExpert(alpha, w_vector, &v_vector);
00205         bool all_positive=true;
00206         zero_coeff.Clear();
00207         double v_sum=0;
00208         for(index_t j=0; j<dimension; j++) {
00209           if (v_vector[j]<0) {
00210             all_positive=false;
00211             zero_coeff.PushBackCopy(j);
00212             v_vector[j]=0;
00213           } else {
00214             v_sum+=v_vector[j];
00215           } 
00216         }
00217         if (all_positive==true) {
00218           break;
00219         }
00220         double temp=(l1_norm-v_sum)/(dimension-zero_coeff.size());
00221         la::AddExpert(temp, ones, &v_vector);
00222         for(index_t j=0; j<zero_coeff.size(); j++) {
00223           v_vector[zero_coeff[j]]=0;
00224         }
00225       }
00226     }
00227   }
00228 
00229 };
00230 
00231 #endif // OPTIMIZATION_UTILS_H_
00232 
Generated on Mon Jan 24 12:04:37 2011 for FASTlib by  doxygen 1.6.3