PLearn 0.1
DoubleAccessSparseMatrix_impl.h
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // DoubleAccessSparseMatrix.cc
00004 // 
00005 // PLearn (A C++ Machine Learning Library)
00006 // Copyright (C) 2002 Christian Jauvin
00007 // 
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions are met:
00010 // 
00011 //  1. Redistributions of source code must retain the above copyright
00012 //     notice, this list of conditions and the following disclaimer.
00013 // 
00014 //  2. Redistributions in binary form must reproduce the above copyright
00015 //     notice, this list of conditions and the following disclaimer in the
00016 //     documentation and/or other materials provided with the distribution.
00017 // 
00018 //  3. The name of the authors may not be used to endorse or promote
00019 //     products derived from this software without specific prior written
00020 //     permission.
00021 // 
00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032 // 
00033 // This file is part of the PLearn library. For more information on the PLearn
00034 // library, go to the PLearn Web site at www.plearn.org
00035 
00036 /* *******************************************************      
00037  * $Id: DoubleAccessSparseMatrix_impl.h 3994 2005-08-25 13:35:03Z chapados $ 
00038  ******************************************************* */
00039 
00042 namespace PLearn {
00043 using namespace std;
00044 
00045 template<class T>
00046 DoubleAccessSparseMatrix<T>::DoubleAccessSparseMatrix(int n_rows, int n_cols, string _name, int _mode, bool _double_access, T _null_elem) : name(_name), mode(_mode), double_access(_double_access), height(n_rows), width(n_cols), null_elem(_null_elem) 
00047 {
00048     if (mode != ROW_WISE && mode != COLUMN_WISE) PLERROR("mode must be either row-wise or column-wise");
00049 
00050     if (double_access)
00051     {
00052         rows.resize(height);
00053         cols.resize(width);
00054     } else if (mode == ROW_WISE)
00055     {
00056         rows.resize(height);
00057     } else
00058     {
00059         cols.resize(width);
00060     }
00061 }
00062 
00063 template <class T>
00064 void DoubleAccessSparseMatrix<T>::resize(int n_rows, int n_cols, bool clear_data) 
00065 {
00066     height = n_rows;
00067     width = n_cols;
00068     if (double_access)
00069     {
00070         rows.resize(n_rows);
00071         cols.resize(n_cols);
00072     } else if (mode == ROW_WISE)
00073     {
00074         rows.resize(n_rows);
00075     } else
00076     {
00077         cols.resize(n_cols);
00078     }
00079     if (clear_data)
00080         clear();
00081 }
00082 
00083 template <class T>
00084 void DoubleAccessSparseMatrix<T>::clear() 
00085 {
00086     if (mode == ROW_WISE || double_access)
00087     {
00088         // norman: added explicit cast
00089         int rs = (int)rows.size();
00090         for (int i = 0; i < rs; i++)
00091             rows[i].clear();
00092     }
00093     if (mode == COLUMN_WISE || double_access)
00094     {
00095         // norman: added explicit cast
00096         int cs = (int)cols.size();
00097         for (int i = 0; i < cs; i++)
00098             cols[i].clear();
00099     }
00100 }
00101 
00102 template <class T>
00103 void DoubleAccessSparseMatrix<T>::clearRow(int i, bool force_synchro_if_double_accessible)
00104 {
00105     if (!double_access)
00106     {
00107         if (mode == COLUMN_WISE)
00108             PLERROR("cannot access rows in the column-wise matrix");
00109         else
00110             rows[i].clear();
00111     } else
00112     {
00113         if (force_synchro_if_double_accessible)
00114         {
00115             for (int j = 0; j < width; j++)
00116             {
00117                 map<int, T>& col_j = cols[j];
00118                 if (col_j.find(i) != col_j.end())
00119                     col_j.erase(i);
00120             }
00121         } else
00122         {
00123             PLWARNING("can only clear rows in the row-wise matrix (internal matrices are now out of sync)");
00124             rows[i].clear();
00125         }
00126     }
00127 }
00128 
00129 template <class T>
00130 void DoubleAccessSparseMatrix<T>::clearCol(int j, bool force_synchro_if_double_accessible)
00131 {
00132     if (!double_access)
00133     {
00134         if (mode == ROW_WISE)
00135             PLERROR("cannot access columns in the row-wise matrix");
00136         else if (mode == COLUMN_WISE)
00137             cols[j].clear();
00138     } else
00139     {
00140         if (force_synchro_if_double_accessible)
00141         {
00142             for (int i = 0; i < height; j++)
00143             {
00144                 map<int, T>& row_i = rows[i];
00145                 if (row_i.find(j) != row_i.end())
00146                     row_i.erase(j);
00147             }
00148         } else
00149         {
00150             PLWARNING("can only clear columns in the column-wise matrix (internal matrices are now out of sync)");
00151             cols[j].clear();
00152         }
00153     }
00154 }
00155 
00156 template <class T>
00157 void DoubleAccessSparseMatrix<T>::clearElem(int i, int j)
00158 {
00159     if (mode == ROW_WISE || double_access)
00160     {
00161         map<int, T>& row_i = rows[i];
00162         if (row_i.find(j) != row_i.end())
00163             row_i.erase(j);
00164     }
00165     if (mode == COLUMN_WISE || double_access)
00166     {
00167         map<int, T>& col_j = cols[j];
00168         if (col_j.find(i) != col_j.end())
00169             col_j.erase(i);
00170     }
00171 }
00172 
00173 template <class T>
00174 T DoubleAccessSparseMatrix<T>::get(int i, int j) const
00175 {
00176 #ifdef BOUNDCHECK      
00177     if (i < 0 || i >= height || j < 0 || j >= width)
00178         PLERROR("out-of-bound access to (%d, %d), dims = (%d, %d)", i, j, height, width);
00179 #endif
00180     if (mode == ROW_WISE)
00181     {
00182         const map<int, T>& row_i = rows[i];
00183         typename map<int, T>::const_iterator it = row_i.find(j);
00184         if (it == row_i.end())
00185             return null_elem;
00186         return it->second;
00187     } else
00188     {
00189         const map<int, T>& col_j = cols[j];
00190         typename map<int, T>::const_iterator it = col_j.find(i);
00191         if (it == col_j.end())
00192             return null_elem;
00193         return it->second;
00194     }
00195 }
00196 
00197 template <class T>
00198 bool DoubleAccessSparseMatrix<T>::exists(int i, int j) const
00199 {
00200 #ifdef BOUNDCHECK      
00201     if (i < 0 || i >= height || j < 0 || j >= width)
00202         PLERROR("out-of-bound access to (%d, %d), dims = (%d, %d)", i, j, height, width);
00203 #endif
00204     if (mode == ROW_WISE)
00205     {
00206         const map<int, T>& row_i = rows[i];
00207         return (row_i.find(j) != row_i.end());
00208     } else
00209     {
00210         const map<int, T>& col_j = cols[j];
00211         return (col_j.find(i) != col_j.end());
00212     }    
00213 }
00214 
00215 template <class T>
00216 void DoubleAccessSparseMatrix<T>::set(int i, int j, T value)
00217 {
00218 #ifdef BOUNDCHECK      
00219     if (i < 0 || i >= height || j < 0 || j >= width)
00220         PLERROR("out-of-bound access to (%d, %d), dims = (%d, %d)", i, j, height, width);
00221 #endif
00222     if (value != null_elem)
00223     {
00224         if (mode == ROW_WISE || double_access)
00225             rows[i][j] = value;
00226         if (mode == COLUMN_WISE || double_access)
00227             cols[j][i] = value;
00228     } else
00229     {
00230         clearElem(i, j);
00231     }
00232 }
00233 
00234 template <class T>
00235 void DoubleAccessSparseMatrix<T>::incr(int i, int j, T inc)
00236 {
00237     if (inc != null_elem)
00238         set(i, j, get(i, j) + inc);
00239 }
00240 
00241 /*
00242   template <class T>
00243   void DoubleAccessSparseMatrix<T>::operator=(SMat<T> m)
00244   {
00245   name = m->getName();
00246   mode = m->getMode();
00247   null_elem = m->getNullElem();
00248   double_access = m->isDoubleAccessible();
00249   clear();
00250   resize(m->getHeight(), m->getWidth());
00251   if (mode == ROW_WISE)
00252   {
00253   for (int i = 0; i < height; i++)
00254   {
00255   map<int, T>& row_i = m->getRow(i);
00256   for (typename map<int, T>::iterator it = row_i.begin(); it != row_i.end(); ++it)
00257   {
00258   int j = it->first;
00259   T val = it->second;
00260   set(i, j, val);
00261   }
00262   }
00263   } else
00264   {
00265   for (int j = 0; j < width; j++)
00266   {
00267   map<int, T>& col_j = m->getCol(j);
00268   for (typename map<int, T>::iterator it = col_j.begin(); it != col_j.end(); ++it)
00269   {
00270   int i = it->first;
00271   T val = it->second;
00272   set(i, j, val);
00273   }
00274   }
00275   }
00276   }
00277 */
00278 
00279 template <class T>
00280 map<int, T>& DoubleAccessSparseMatrix<T>::getRow(int i)
00281 {
00282     if (mode == ROW_WISE || double_access)
00283     {
00284 #ifdef BOUNDCHECK
00285         if (i < 0 || i > height)
00286             PLERROR("out-of-bound access to row %d, dims = (%d, %d)", i, height, width);
00287 #endif
00288         return rows[i];
00289     } else
00290     {
00291         PLERROR("cannot access rows in the column-wise matrix");
00292         return rows[0];
00293     }
00294 }
00295 
00296 template <class T>
00297 const map<int, T>& DoubleAccessSparseMatrix<T>::getCol(int j)const
00298 {
00299     if (mode == COLUMN_WISE || double_access)
00300     {
00301 #ifdef BOUNDCHECK
00302         if (j < 0 || j > width)
00303             PLERROR("out-of-bound access to column %d, dims = (%d, %d)", j, height, width);
00304 #endif
00305         return cols[j];
00306     } else
00307     {
00308         PLERROR("cannot access columns in the row-wise matrix");
00309         return cols[0];
00310     }
00311 }
00312 
00313 template <class T>
00314 void DoubleAccessSparseMatrix<T>::addRow(map<int, T>& row)
00315 {
00316     if (mode == COLUMN_WISE || double_access)
00317     {
00318         PLERROR("cannot add row in the column-wise matrix");
00319     } else
00320     {
00321         rows.push_back(row);
00322         height++;
00323     }
00324 }
00325 
00326 template <class T>
00327 void DoubleAccessSparseMatrix<T>::addCol(map<int, T>& col)
00328 {
00329     if (mode == ROW_WISE || double_access)
00330     {
00331         PLERROR("cannot add col in the row-wise matrix");
00332     } else
00333     {
00334         cols.push_back(col);
00335         width++;
00336     }
00337 }
00338 
00339 template <class T>
00340 int DoubleAccessSparseMatrix<T>::size()
00341 {
00342     int s = 0;
00343     if (mode == ROW_WISE)
00344     {
00345         for (unsigned int i = 0; i < rows.size(); i++)
00346             // norman: added explicit cast
00347             s += (int)rows[i].size();
00348     } else
00349     {
00350         for (unsigned int j = 0; j < cols.size(); j++)
00351             // norman: added explicit cast
00352             s += (int)cols[j].size();
00353     }
00354     return s;
00355 }
00356 
00357 template <class T>
00358 T DoubleAccessSparseMatrix<T>::sumRow(int i) 
00359 {
00360     if (mode == ROW_WISE || double_access)
00361     {
00362         T sum = 0;
00363         map<int, T>& row_i = rows[i];
00364         for (typename map<int, T>::iterator it = row_i.begin(); it != row_i.end(); ++it)
00365             sum += it->second;
00366         return sum;
00367     } else
00368     {
00369         PLERROR("cannot access rows in the column-wise matrix");
00370         return 0;
00371     }
00372 }
00373 
00374 template <class T>
00375 T DoubleAccessSparseMatrix<T>::sumCol(int j) 
00376 {
00377     if (mode == COLUMN_WISE || double_access)
00378     {
00379         T sum = 0;
00380         map<int, T>& col_j = cols[j];
00381         for (typename map<int, T>::iterator it = col_j.begin(); it != col_j.end(); ++it)
00382             sum += it->second;
00383         return sum;
00384     } else
00385     {
00386         PLERROR("cannot access columns in the row-wise matrix");
00387         return 0;
00388     }
00389 }
00390 
00391 template <class T>
00392 T* DoubleAccessSparseMatrix<T>::getAsCompressedVec()
00393 {
00394     int vector_size = size() * 3;
00395     T* compressed_vec = NULL;
00396     int pos = 0;
00397     if (mode == ROW_WISE || double_access)
00398     {
00399         compressed_vec = new T[vector_size];
00400         for (int i = 0; i < height; i++)
00401         {
00402             map<int, T>& row_i = rows[i];
00403             for (typename map<int, T>::iterator it = row_i.begin(); it != row_i.end(); ++it)
00404             {
00405                 int j = it->first;
00406                 T value = it->second;
00407                 compressed_vec[pos++] = (T)i;
00408                 compressed_vec[pos++] = (T)j;
00409                 compressed_vec[pos++] = value;
00410             }
00411         }
00412         if (pos != vector_size)
00413             PLERROR("weird");
00414     } else if (mode == COLUMN_WISE)
00415     {
00416         compressed_vec = new T[vector_size];
00417         for (int j = 0; j < width; j++)
00418         {
00419             map<int, T>& col_j = cols[j];
00420             for (typename map<int, T>::iterator it = col_j.begin(); it != col_j.end(); ++it)
00421             {
00422                 int i = it->first;
00423                 T value = it->second;
00424                 compressed_vec[pos++] = (T)i;
00425                 compressed_vec[pos++] = (T)j;
00426                 compressed_vec[pos++] = value;
00427             }
00428         }
00429         if (pos != vector_size)
00430             PLERROR("weird");
00431     }
00432     return compressed_vec;
00433 }
00434 
00435 template <class T>
00436 void DoubleAccessSparseMatrix<T>::getAsMaxSizedCompressedVecs(int max_size, vector<pair<T*, int> >& vectors)
00437 {
00438     if ((max_size % 3) != 0) PLWARNING("dangerous vector size (max_size mod 3 must equal 0)");
00439 
00440     int n_elems = size() * 3;
00441     int n_vecs = n_elems / max_size;
00442     int remaining = n_elems % max_size;
00443     int pos = 0;
00444     if (remaining > 0) // padding to get sure that last block size (= remaining) is moddable by 3
00445     {
00446         n_vecs += 1;
00447         int mod3 = remaining % 3;
00448         if (mod3 != 0)
00449             remaining += (3 - mod3);
00450     }
00451     vectors.resize(n_vecs);
00452     for (int i = 0; i < n_vecs; i++)
00453     {
00454         if (i == (n_vecs - 1) && remaining > 0)
00455         {
00456             vectors[i].first = new T[remaining];
00457             vectors[i].second = remaining;
00458         } else
00459         {
00460             vectors[i].first = new T[max_size];
00461             vectors[i].second = max_size;
00462         }
00463     }
00464     if (mode == ROW_WISE)
00465     {
00466         for (int i = 0; i < height; i++)
00467         {
00468             map<int, T>& row_i = rows[i];
00469             for (typename map<int, T>::iterator it = row_i.begin(); it != row_i.end(); ++it)
00470             {
00471                 int j = it->first;
00472                 T value = it->second;
00473                 vectors[pos / max_size].first[pos++ % max_size] = (T)i;
00474                 vectors[pos / max_size].first[pos++ % max_size] = (T)j;
00475                 vectors[pos / max_size].first[pos++ % max_size] = value;
00476             }
00477         }
00478     } else if (mode == COLUMN_WISE)
00479     {
00480         for (int j = 0; j < width; j++)
00481         {
00482             map<int, T>& col_j = cols[j];
00483             for (typename map<int, T>::iterator it = col_j.begin(); it != col_j.end(); ++it)
00484             {
00485                 int i = it->first;
00486                 T value = it->second;
00487                 vectors[pos / max_size].first[pos++ % max_size] = (T)i;
00488                 vectors[pos / max_size].first[pos++ % max_size] = (T)j;
00489                 vectors[pos / max_size].first[pos++ % max_size] = value;
00490             }
00491         }
00492     }
00493     while (pos < n_elems) // pad with (null_elem, null_elem, null_elem)
00494     {
00495         vectors[pos / max_size].first[pos++ % max_size] = null_elem;
00496         vectors[pos / max_size].first[pos++ % max_size] = null_elem;
00497         vectors[pos / max_size].first[pos++ % max_size] = null_elem;
00498     }
00499 }
00500 
00501 template <class T>
00502 void DoubleAccessSparseMatrix<T>::addCompressedVec(T* compressed_vec, int n_elems)
00503 {
00504     if ((n_elems % 3) != 0) PLERROR("n_elems mod 3 must = 0");
00505     for (int i = 0; i < n_elems; i += 3)
00506         incr((int)compressed_vec[i], (int)compressed_vec[i + 1], compressed_vec[i + 2]);
00507 }
00508 
00509 template <class T>
00510 void DoubleAccessSparseMatrix<T>::setCompressedVec(T* compressed_vec, int n_elems)
00511 {
00512     if ((n_elems % 3) != 0) PLERROR("n_elems mod 3 must = 0");
00513     clear();
00514     for (int i = 0; i < n_elems; i += 3)
00515         set((int)compressed_vec[i], (int)compressed_vec[i + 1], compressed_vec[i + 2]);
00516 }
00517 
00518 template <class T> 
00519 T DoubleAccessSparseMatrix<T>::sumOfElements()
00520 {
00521     T sum = 0;
00522     if (mode == ROW_WISE)
00523     {
00524         for (int i = 0; i < height; i++)
00525         {
00526             map<int, T>& row_i = rows[i];
00527             for (typename map<int, T>::iterator it = row_i.begin(); it != row_i.end(); ++it)
00528                 sum += it->second;
00529         }
00530     } else if (mode == COLUMN_WISE)
00531     {
00532         for (int j = 0; j < width; j++)
00533         {
00534             map<int, T>& col_j = cols[j];
00535             for (typename map<int, T>::iterator it = col_j.begin(); it != col_j.end(); ++it)
00536                 sum += it->second;
00537         }
00538     }
00539     return sum;
00540 }
00541 
00542 template <class T>
00543 void DoubleAccessSparseMatrix<T>::setDoubleAccessible(bool da)
00544 {
00545     if (double_access != da)
00546     {
00547         double_access = da;
00548         if (!double_access)
00549         {
00550             if (mode == ROW_WISE)
00551                 cols.clear();
00552             else if (mode == COLUMN_WISE)
00553                 rows.clear();
00554         } else
00555         {
00556             if (mode == ROW_WISE)
00557             {
00558                 cols.resize(width);
00559                 for (int i = 0; i < height; i++)
00560                 {
00561                     map<int, T>& row_i = rows[i];
00562                     for (typename map<int, T>::iterator it = row_i.begin(); it != row_i.end(); ++it)
00563                     {
00564                         int j = it->first;
00565                         T value = it->second;
00566                         set(i, j, value);
00567                     }
00568                 }
00569             } else if (mode == COLUMN_WISE)
00570             {
00571                 rows.resize(height);
00572                 for (int j = 0; j < width; j++)
00573                 {
00574                     map<int, T>& col_j = cols[j];
00575                     for (typename map<int, T>::iterator it = col_j.begin(); it != col_j.end(); ++it)
00576                     {
00577                         int i = it->first;
00578                         T value = it->second;
00579                         set(i, j, value);
00580                     }
00581                 }
00582             } 
00583         }
00584     }
00585 }
00586 
00587 template <class T>
00588 void DoubleAccessSparseMatrix<T>::setMode(int new_mode)
00589 {
00590     if (mode != ROW_WISE && mode != COLUMN_WISE) PLERROR("mode must be either row-wise or column-wise");
00591 
00592     if (mode != new_mode)
00593     {
00594         mode = new_mode;
00595         if (mode == ROW_WISE && !double_access)
00596         {
00597             rows.resize(height);
00598             for (int j = 0; j < width; j++)
00599             {
00600                 map<int, T>& col_j = cols[j];
00601                 for (typename map<int, T>::iterator it = col_j.begin(); it != col_j.end(); ++it)
00602                 {
00603                     int i = it->first;
00604                     T value = it->second;
00605                     set(i, j, value);
00606                 }
00607             }
00608             cols.clear();
00609         } else if (mode == COLUMN_WISE && !double_access)
00610         {
00611             cols.resize(width);
00612             for (int i = 0; i < height; i++)
00613             {
00614                 map<int, T>& row_i = rows[i];
00615                 for (typename map<int, T>::iterator it = row_i.begin(); it != row_i.end(); ++it)
00616                 {
00617                     int j = it->first;
00618                     T value = it->second;
00619                     set(i, j, value);
00620                 }
00621             }
00622             rows.clear();
00623         }
00624     }
00625 }
00626 
00627 template <class T>
00628 void DoubleAccessSparseMatrix<T>::write(PStream& out) const
00629 {
00630     string class_name = getClassName();
00631     switch(out.outmode)
00632     {
00633     case PStream::raw_ascii :
00634     case PStream::pretty_ascii :
00635         PLERROR("raw/pretty_ascii write not implemented in %s", class_name.c_str());
00636         break;        
00637     case PStream::raw_binary :
00638         PLERROR("raw_binary write not implemented in %s", class_name.c_str());
00639         break;        
00640     case PStream::plearn_binary :
00641     case PStream::plearn_ascii :
00642         out.write(class_name + "(");
00643         out << rows;
00644         out << cols;
00645         out << name;
00646         out << mode;
00647         out << double_access;
00648         out << height;
00649         out << width;
00650         out << null_elem;
00651         out.write(")\n");
00652         break;
00653     default:
00654         PLERROR("unknown outmode in %s::write(PStream& out)", class_name.c_str());
00655         break;
00656     }
00657 }
00658 
00659 template <class T>
00660 void DoubleAccessSparseMatrix<T>::read(PStream& in)
00661 {
00662     string class_name = getClassName();
00663     switch (in.inmode)
00664     {
00665     case PStream::raw_ascii :
00666         PLERROR("raw_ascii read not implemented in %s", class_name.c_str());
00667         break;
00668     case PStream::raw_binary :
00669         PLERROR("raw_binary read not implemented in %s", class_name.c_str());
00670         break;
00671     case PStream::plearn_ascii :
00672     case PStream::plearn_binary :
00673     {
00674         in.skipBlanksAndCommentsAndSeparators();
00675         string word(class_name.size() + 1, ' ');
00676         for (unsigned int i = 0; i < class_name.size() + 1; i++)
00677             in.get(word[i]);
00678         if (word != class_name + "(")
00679             PLERROR("in %s::(PStream& in), '%s' is not a proper header", class_name.c_str(), word.c_str());
00680         in.skipBlanksAndCommentsAndSeparators();
00681         in >> rows;
00682         in.skipBlanksAndCommentsAndSeparators();
00683         in >> cols;
00684         in.skipBlanksAndCommentsAndSeparators();
00685         in >> name;
00686         in.skipBlanksAndCommentsAndSeparators();
00687         in >> mode;
00688         in.skipBlanksAndCommentsAndSeparators();
00689         in >> double_access;
00690         in.skipBlanksAndCommentsAndSeparators();
00691         in >> height;
00692         in.skipBlanksAndCommentsAndSeparators();
00693         in >> width;
00694         in.skipBlanksAndCommentsAndSeparators();
00695         in >> null_elem;
00696         in.skipBlanksAndCommentsAndSeparators();
00697         int c = in.get();
00698         if(c != ')')
00699             PLERROR("in %s::(PStream& in), expected a closing parenthesis, found '%c'", class_name.c_str(), c);
00700     }
00701     break;
00702     default:
00703         PLERROR("unknown inmode in %s::write(PStream& out)", class_name.c_str());
00704         break;
00705     }
00706 }
00707 
00708 } // end of namespace PLearn
00709 
00710 
00711 /*
00712   Local Variables:
00713   mode:c++
00714   c-basic-offset:4
00715   c-file-style:"stroustrup"
00716   c-file-offsets:((innamespace . 0)(inline-open . 0))
00717   indent-tabs-mode:nil
00718   fill-column:79
00719   End:
00720 */
00721 // 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