optimization_utils.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
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
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
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
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
00172
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
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