PLearn 0.1
RowMapSparseValueMatrix.h
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // PLearn (A C++ Machine Learning Library)
00004 // Copyright (C) 2003 Marie Ouimet
00005 //
00006 
00007 // Redistribution and use in source and binary forms, with or without
00008 // modification, are permitted provided that the following conditions are met:
00009 // 
00010 //  1. Redistributions of source code must retain the above copyright
00011 //     notice, this list of conditions and the following disclaimer.
00012 // 
00013 //  2. Redistributions in binary form must reproduce the above copyright
00014 //     notice, this list of conditions and the following disclaimer in the
00015 //     documentation and/or other materials provided with the distribution.
00016 // 
00017 //  3. The name of the authors may not be used to endorse or promote
00018 //     products derived from this software without specific prior written
00019 //     permission.
00020 // 
00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031 // 
00032 // This file is part of the PLearn library. For more information on the PLearn
00033 // library, go to the PLearn Web site at www.plearn.org
00034 
00037 #ifndef ROWMAPSPARSEVALUEMATRIX
00038 #define ROWMAPSPARSEVALUEMATRIX
00039 
00040 #include "RowMapSparseMatrix.h"
00041 
00042 namespace PLearn {
00043 using namespace std;
00044 
00074 template <class T>
00075 class RowMapSparseValueMatrix: public RowMapSparseMatrix<T> {
00076 public:
00077 
00078     T value;
00079 
00080     RowMapSparseValueMatrix(T value_=0, int n_rows=0, int n_columns=0) 
00081         : RowMapSparseMatrix<T>(n_rows, n_columns), value(value_)
00082     {}
00083 
00084     RowMapSparseValueMatrix(T value_, string filename)
00085         : RowMapSparseMatrix<T>(filename), value(value_)
00086     {}
00087 
00088     RowMapSparseValueMatrix(T value_, const Mat& m, int fill_mode=0) 
00089         :  RowMapSparseMatrix<T>(m.length(), m.width()), value(value_)
00090     {
00091         switch(fill_mode){
00092         case 0:
00093             //fill all
00094             for (int i=0;i<length();i++)
00095             {
00096                 real* r=m[i];
00097                 map<int,T>& row_i=rows[i];
00098                 for (int j=0;j<width();j++)
00099                     row_i[j]=T(r[j]);
00100             }
00101             break;
00102         case 1:
00103             //fill only if entry != value 
00104             for (int i=0;i<length();i++)
00105             {
00106                 real* r=m[i];
00107                 map<int,T>& row_i=rows[i];
00108                 for (int j=0;j<width();j++){
00109                     if(T(r[j])!=value_)
00110                         row_i[j]=T(r[j]);
00111                 }
00112             }
00113             break;
00114         case 2:
00115             //fill only if entry < value 
00116             for (int i=0;i<length();i++)
00117             {
00118                 real* r=m[i];
00119                 map<int,T>& row_i=rows[i];
00120                 for (int j=0;j<width();j++){
00121                     if(T(r[j])<value_)
00122                         row_i[j]=T(r[j]);
00123                 }
00124             }
00125             break;
00126         default:
00127             PLERROR("RowMapSparseValueMatrix: fill_mode must be 0, 1 or 2.");
00128         }
00129     }
00130 
00132     RowMapSparseValueMatrix(T value_, const SparseMatrix& sm, int n_rows, int n_cols) 
00133         : RowMapSparseMatrix<T>(sm, n_rows, n_cols), value(value_)
00134     {}
00135 
00136     Mat toMat() 
00137     {
00138         Mat res(length(),width(),value);
00139         for (int i=0;i<length();i++)
00140         {
00141             map<int,T>& row_i = rows[i];
00142             typename map<int,T>::const_iterator it = row_i.begin();
00143             typename map<int,T>::const_iterator end = row_i.end();
00144             real* res_i=res[i];
00145             for (;it!=end;++it)
00146                 res_i[it->first] = it->second;
00147         }
00148         return res;
00149     }
00150 
00151 
00152     T& operator()(int i, int j) { 
00153 #ifdef BOUNDCHECK      
00154         if (i<0 || i>=length() && j<0 || j>=width())
00155             PLERROR("RowMapSparseValueMatrix: out-of-bound access to (%d,%d), dims=(%d,%d)",
00156                     i,j,length(),width());
00157 #endif
00158         return rows[i][j];
00159     }
00160 
00161     const T& operator()(int i, int j) const { 
00162 #ifdef BOUNDCHECK      
00163         if (i<0 || i>=length() && j<0 || j>=width())
00164             PLERROR("RowMapSparseValueMatrix: out-of-bound access to (%d,%d), dims=(%d,%d)",
00165                     i,j,length(),width());
00166 #endif
00167         const map<int,T>& row_i = rows[i];
00168         typename map<int,T>::const_iterator it = row_i.find(j);
00169         if (it==row_i.end())
00170             return value;
00171         return it->second;
00172     }
00173 
00186     map<int,T>& operator()(int i) { return rows[i]; }
00187 
00188 
00189 
00195     void averageAcrossRowsAndColumns(Vec avg_across_rows, Vec avg_across_columns,
00196                                      bool only_on_non_value=false){
00197         avg_across_rows.resize(width());
00198         avg_across_columns.resize(length());
00199         avg_across_rows.clear();
00200         avg_across_columns.clear();
00201         TVec<int> column_counts(width());
00202 
00203         if (only_on_non_value){
00204             for (int i=0;i<length();i++)
00205             {
00206                 real& avg_cols_i=avg_across_columns[i];
00207                 real* avg_rows = avg_across_rows.data();
00208                 map<int,T>& row_i = rows[i];
00209                 typename map<int,T>::const_iterator it = row_i.begin();
00210                 typename map<int,T>::const_iterator end = row_i.end();
00211                 int n=0;
00212                 for (;it!=end;++it)
00213                 {
00214                     avg_cols_i += it->second;
00215                     int j=it->first;
00216                     avg_rows[j] += it->second;
00217                     n++;
00218                     column_counts[j]++;
00219                 }
00220                 avg_cols_i /= n;
00221             }
00222             for (int j=0;j<width();j++)
00223                 avg_across_rows[j] /= column_counts[j];
00224         }
00225         else {
00226             for (int i=0;i<length();i++)
00227             {
00228                 real& avg_cols_i=avg_across_columns[i];
00229                 real* avg_rows = avg_across_rows.data();
00230                 map<int,T>& row_i = rows[i];
00231                 typename map<int,T>::const_iterator it = row_i.begin();
00232                 typename map<int,T>::const_iterator end = row_i.end();
00233                 int n=0;
00234                 for (;it!=end;++it)
00235                 {
00236                     avg_cols_i += it->second;
00237                     int j=it->first;
00238                     avg_rows[j] += it->second;
00239                     n++;
00240                     column_counts[j]++;
00241                 }
00242                 avg_cols_i += value*(width()-n);
00243                 avg_cols_i /= width(); //store average of ith row
00244             }
00245             //compute average of each column
00246             for (int j=0;j<width();j++){
00247                 avg_across_rows[j] += value*(length() - column_counts[j]);
00248                 avg_across_rows[j] /= length();
00249             }
00250         }
00251     }
00252 
00253     real euclidianDistance(map<int, real>& map1, map<int, real>& map2) {
00254         if (map1.size() == 0 || map2.size() == 0)
00255             return 0;
00256         map<int, real>::iterator beg1 = map1.begin();
00257         map<int, real>::iterator beg2 = map2.begin();
00258         map<int, real>::iterator end1 = map1.end();
00259         map<int, real>::iterator end2 = map2.end();
00260         int col1, col2;
00261         real val1, val2, diff, sum = 0;
00262         bool fend1 = (beg1 == end1), fend2 = (beg2 == end2);
00263         int OUT = getMaxColumnIndex(map1, map2) + 1;
00264         
00265         while (!fend1 || !fend2) 
00266         {
00267             if (!fend1)
00268                 col1 = beg1->first;
00269             else
00270                 col1 = OUT;
00271             if (!fend2)
00272                 col2 = beg2->first;
00273             else
00274                 col2 = OUT;
00275             val1 = beg1->second;
00276             val2 = beg2->second;
00277             if (col1 == col2) 
00278             {
00279                 diff = val1 - val2;
00280                 sum += (diff * diff);
00281                 beg1++;
00282                 if (beg1 == end1) fend1 = true;
00283                 beg2++;
00284                 if (beg2 == end2) fend2 = true;
00285             } else if (col1 < col2) 
00286             {
00287                 diff = val1 - value;
00288                 sum += (diff * diff);
00289                 beg1++;
00290                 if (beg1 == end1) fend1 = true;
00291             } else if (col1 > col2) 
00292             {
00293                 diff = value - val2;
00294                 sum += (diff * diff);
00295                 beg2++;
00296                 if (beg2 == end2) fend2 = true;
00297             }
00298         }
00299         //return sqrt(sum);
00301         return sum;
00302     }
00303 
00304 };
00305 
00306 
00307 } // end of namespace PLearn
00308 
00309 #endif
00310 
00311 
00312 /*
00313   Local Variables:
00314   mode:c++
00315   c-basic-offset:4
00316   c-file-style:"stroustrup"
00317   c-file-offsets:((innamespace . 0)(inline-open . 0))
00318   indent-tabs-mode:nil
00319   fill-column:79
00320   End:
00321 */
00322 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines