Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

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,v 1.5 2004/02/26 07:06:55 nova77 Exp $ 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) 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 clear(); 00080 } 00081 00082 template <class T> 00083 void DoubleAccessSparseMatrix<T>::clear() 00084 { 00085 if (mode == ROW_WISE || double_access) 00086 { 00087 // norman: added explicit cast 00088 int rs = (int)rows.size(); 00089 for (int i = 0; i < rs; i++) 00090 rows[i].clear(); 00091 } 00092 if (mode == COLUMN_WISE || double_access) 00093 { 00094 // norman: added explicit cast 00095 int cs = (int)cols.size(); 00096 for (int i = 0; i < cs; i++) 00097 cols[i].clear(); 00098 } 00099 } 00100 00101 template <class T> 00102 void DoubleAccessSparseMatrix<T>::clearRow(int i, bool force_synchro_if_double_accessible) 00103 { 00104 if (!double_access) 00105 { 00106 if (mode == COLUMN_WISE) 00107 PLERROR("cannot access rows in the column-wise matrix"); 00108 else 00109 rows[i].clear(); 00110 } else 00111 { 00112 if (force_synchro_if_double_accessible) 00113 { 00114 for (int j = 0; j < width; j++) 00115 { 00116 map<int, T>& col_j = cols[j]; 00117 if (col_j.find(i) != col_j.end()) 00118 col_j.erase(i); 00119 } 00120 } else 00121 { 00122 PLWARNING("can only clear rows in the row-wise matrix (internal matrices are now out of sync)"); 00123 rows[i].clear(); 00124 } 00125 } 00126 } 00127 00128 template <class T> 00129 void DoubleAccessSparseMatrix<T>::clearCol(int j, bool force_synchro_if_double_accessible) 00130 { 00131 if (!double_access) 00132 { 00133 if (mode == ROW_WISE) 00134 PLERROR("cannot access columns in the row-wise matrix"); 00135 else if (mode == COLUMN_WISE) 00136 cols[j].clear(); 00137 } else 00138 { 00139 if (force_synchro_if_double_accessible) 00140 { 00141 for (int i = 0; i < height; j++) 00142 { 00143 map<int, T>& row_i = rows[i]; 00144 if (row_i.find(j) != row_i.end()) 00145 row_i.erase(j); 00146 } 00147 } else 00148 { 00149 PLWARNING("can only clear columns in the column-wise matrix (internal matrices are now out of sync)"); 00150 cols[j].clear(); 00151 } 00152 } 00153 } 00154 00155 template <class T> 00156 void DoubleAccessSparseMatrix<T>::clearElem(int i, int j) 00157 { 00158 if (mode == ROW_WISE || double_access) 00159 { 00160 map<int, T>& row_i = rows[i]; 00161 if (row_i.find(j) != row_i.end()) 00162 row_i.erase(j); 00163 } 00164 if (mode == COLUMN_WISE || double_access) 00165 { 00166 map<int, T>& col_j = cols[j]; 00167 if (col_j.find(i) != col_j.end()) 00168 col_j.erase(i); 00169 } 00170 } 00171 00172 template <class T> 00173 T DoubleAccessSparseMatrix<T>::get(int i, int j) 00174 { 00175 #ifdef BOUNDCHECK 00176 if (i < 0 || i >= height || j < 0 || j >= width) 00177 PLERROR("out-of-bound access to (%d, %d), dims = (%d, %d)", i, j, height, width); 00178 #endif 00179 if (mode == ROW_WISE) 00180 { 00181 map<int, T>& row_i = rows[i]; 00182 typename map<int, T>::iterator it = row_i.find(j); 00183 if (it == row_i.end()) 00184 return null_elem; 00185 return it->second; 00186 } else 00187 { 00188 map<int, T>& col_j = cols[j]; 00189 typename map<int, T>::iterator it = col_j.find(i); 00190 if (it == col_j.end()) 00191 return null_elem; 00192 return it->second; 00193 } 00194 } 00195 00196 template <class T> 00197 bool DoubleAccessSparseMatrix<T>::exists(int i, int j) 00198 { 00199 #ifdef BOUNDCHECK 00200 if (i < 0 || i >= height || j < 0 || j >= width) 00201 PLERROR("out-of-bound access to (%d, %d), dims = (%d, %d)", i, j, height, width); 00202 #endif 00203 if (mode == ROW_WISE) 00204 { 00205 map<int, T>& row_i = rows[i]; 00206 return (row_i.find(j) != row_i.end()); 00207 } else 00208 { 00209 map<int, T>& col_j = cols[j]; 00210 return (col_j.find(i) != col_j.end()); 00211 } 00212 } 00213 00214 template <class T> 00215 void DoubleAccessSparseMatrix<T>::set(int i, int j, T value) 00216 { 00217 #ifdef BOUNDCHECK 00218 if (i < 0 || i >= height || j < 0 || j >= width) 00219 PLERROR("out-of-bound access to (%d, %d), dims = (%d, %d)", i, j, height, width); 00220 #endif 00221 if (value != null_elem) 00222 { 00223 if (mode == ROW_WISE || double_access) 00224 rows[i][j] = value; 00225 if (mode == COLUMN_WISE || double_access) 00226 cols[j][i] = value; 00227 } else 00228 { 00229 clearElem(i, j); 00230 } 00231 } 00232 00233 template <class T> 00234 void DoubleAccessSparseMatrix<T>::incr(int i, int j, T inc) 00235 { 00236 if (inc != null_elem) 00237 set(i, j, get(i, j) + inc); 00238 } 00239 00240 /* 00241 template <class T> 00242 void DoubleAccessSparseMatrix<T>::operator=(SMat<T> m) 00243 { 00244 name = m->getName(); 00245 mode = m->getMode(); 00246 null_elem = m->getNullElem(); 00247 double_access = m->isDoubleAccessible(); 00248 clear(); 00249 resize(m->getHeight(), m->getWidth()); 00250 if (mode == ROW_WISE) 00251 { 00252 for (int i = 0; i < height; i++) 00253 { 00254 map<int, T>& row_i = m->getRow(i); 00255 for (typename map<int, T>::iterator it = row_i.begin(); it != row_i.end(); ++it) 00256 { 00257 int j = it->first; 00258 T val = it->second; 00259 set(i, j, val); 00260 } 00261 } 00262 } else 00263 { 00264 for (int j = 0; j < width; j++) 00265 { 00266 map<int, T>& col_j = m->getCol(j); 00267 for (typename map<int, T>::iterator it = col_j.begin(); it != col_j.end(); ++it) 00268 { 00269 int i = it->first; 00270 T val = it->second; 00271 set(i, j, val); 00272 } 00273 } 00274 } 00275 } 00276 */ 00277 00278 template <class T> 00279 map<int, T>& DoubleAccessSparseMatrix<T>::getRow(int i) 00280 { 00281 if (mode == ROW_WISE || double_access) 00282 { 00283 #ifdef BOUNDCHECK 00284 if (i < 0 || i > height) 00285 PLERROR("out-of-bound access to row %d, dims = (%d, %d)", i, height, width); 00286 #endif 00287 return rows[i]; 00288 } else 00289 { 00290 PLERROR("cannot access rows in the column-wise matrix"); 00291 return rows[0]; 00292 } 00293 } 00294 00295 template <class T> 00296 map<int, T>& DoubleAccessSparseMatrix<T>::getCol(int j) 00297 { 00298 if (mode == COLUMN_WISE || double_access) 00299 { 00300 #ifdef BOUNDCHECK 00301 if (j < 0 || j > width) 00302 PLERROR("out-of-bound access to column %d, dims = (%d, %d)", j, height, width); 00303 #endif 00304 return cols[j]; 00305 } else 00306 { 00307 PLERROR("cannot access columns in the row-wise matrix"); 00308 return cols[0]; 00309 } 00310 } 00311 00312 template <class T> 00313 void DoubleAccessSparseMatrix<T>::addRow(map<int, T>& row) 00314 { 00315 if (mode == COLUMN_WISE || double_access) 00316 { 00317 PLERROR("cannot add row in the column-wise matrix"); 00318 } else 00319 { 00320 rows.push_back(row); 00321 height++; 00322 } 00323 } 00324 00325 template <class T> 00326 void DoubleAccessSparseMatrix<T>::addCol(map<int, T>& col) 00327 { 00328 if (mode == ROW_WISE || double_access) 00329 { 00330 PLERROR("cannot add col in the row-wise matrix"); 00331 } else 00332 { 00333 cols.push_back(col); 00334 width++; 00335 } 00336 } 00337 00338 template <class T> 00339 int DoubleAccessSparseMatrix<T>::size() 00340 { 00341 int s = 0; 00342 if (mode == ROW_WISE) 00343 { 00344 for (unsigned int i = 0; i < rows.size(); i++) 00345 // norman: added explicit cast 00346 s += (int)rows[i].size(); 00347 } else 00348 { 00349 for (unsigned int j = 0; j < cols.size(); j++) 00350 // norman: added explicit cast 00351 s += (int)cols[j].size(); 00352 } 00353 return s; 00354 } 00355 00356 template <class T> 00357 T DoubleAccessSparseMatrix<T>::sumRow(int i) 00358 { 00359 if (mode == ROW_WISE || double_access) 00360 { 00361 T sum = 0; 00362 map<int, T>& row_i = rows[i]; 00363 for (typename map<int, T>::iterator it = row_i.begin(); it != row_i.end(); ++it) 00364 sum += it->second; 00365 return sum; 00366 } else 00367 { 00368 PLERROR("cannot access rows in the column-wise matrix"); 00369 return 0; 00370 } 00371 } 00372 00373 template <class T> 00374 T DoubleAccessSparseMatrix<T>::sumCol(int j) 00375 { 00376 if (mode == COLUMN_WISE || double_access) 00377 { 00378 T sum = 0; 00379 map<int, T>& col_j = cols[j]; 00380 for (typename map<int, T>::iterator it = col_j.begin(); it != col_j.end(); ++it) 00381 sum += it->second; 00382 return sum; 00383 } else 00384 { 00385 PLERROR("cannot access columns in the row-wise matrix"); 00386 return 0; 00387 } 00388 } 00389 00390 template <class T> 00391 T* DoubleAccessSparseMatrix<T>::getAsCompressedVec() 00392 { 00393 int vector_size = size() * 3; 00394 T* compressed_vec = NULL; 00395 int pos = 0; 00396 if (mode == ROW_WISE || double_access) 00397 { 00398 compressed_vec = new T[vector_size]; 00399 for (int i = 0; i < height; i++) 00400 { 00401 map<int, T>& row_i = rows[i]; 00402 for (typename map<int, T>::iterator it = row_i.begin(); it != row_i.end(); ++it) 00403 { 00404 int j = it->first; 00405 T value = it->second; 00406 compressed_vec[pos++] = (T)i; 00407 compressed_vec[pos++] = (T)j; 00408 compressed_vec[pos++] = value; 00409 } 00410 } 00411 if (pos != vector_size) 00412 PLERROR("weird"); 00413 } else if (mode == COLUMN_WISE) 00414 { 00415 compressed_vec = new T[vector_size]; 00416 for (int j = 0; j < width; j++) 00417 { 00418 map<int, T>& col_j = cols[j]; 00419 for (typename map<int, T>::iterator it = col_j.begin(); it != col_j.end(); ++it) 00420 { 00421 int i = it->first; 00422 T value = it->second; 00423 compressed_vec[pos++] = (T)i; 00424 compressed_vec[pos++] = (T)j; 00425 compressed_vec[pos++] = value; 00426 } 00427 } 00428 if (pos != vector_size) 00429 PLERROR("weird"); 00430 } 00431 return compressed_vec; 00432 } 00433 00434 template <class T> 00435 void DoubleAccessSparseMatrix<T>::getAsMaxSizedCompressedVecs(int max_size, vector<pair<T*, int> >& vectors) 00436 { 00437 if ((max_size % 3) != 0) PLWARNING("dangerous vector size (max_size mod 3 must equal 0)"); 00438 00439 int n_elems = size() * 3; 00440 int n_vecs = n_elems / max_size; 00441 int remaining = n_elems % max_size; 00442 int pos = 0; 00443 if (remaining > 0) // padding to get sure that last block size (= remaining) is moddable by 3 00444 { 00445 n_vecs += 1; 00446 int mod3 = remaining % 3; 00447 if (mod3 != 0) 00448 remaining += (3 - mod3); 00449 } 00450 vectors.resize(n_vecs); 00451 for (int i = 0; i < n_vecs; i++) 00452 { 00453 if (i == (n_vecs - 1) && remaining > 0) 00454 { 00455 vectors[i].first = new T[remaining]; 00456 vectors[i].second = remaining; 00457 } else 00458 { 00459 vectors[i].first = new T[max_size]; 00460 vectors[i].second = max_size; 00461 } 00462 } 00463 if (mode == ROW_WISE) 00464 { 00465 for (int i = 0; i < height; i++) 00466 { 00467 map<int, T>& row_i = rows[i]; 00468 for (typename map<int, T>::iterator it = row_i.begin(); it != row_i.end(); ++it) 00469 { 00470 int j = it->first; 00471 T value = it->second; 00472 vectors[pos / max_size].first[pos++ % max_size] = (T)i; 00473 vectors[pos / max_size].first[pos++ % max_size] = (T)j; 00474 vectors[pos / max_size].first[pos++ % max_size] = value; 00475 } 00476 } 00477 } else if (mode == COLUMN_WISE) 00478 { 00479 for (int j = 0; j < width; j++) 00480 { 00481 map<int, T>& col_j = cols[j]; 00482 for (typename map<int, T>::iterator it = col_j.begin(); it != col_j.end(); ++it) 00483 { 00484 int i = it->first; 00485 T value = it->second; 00486 vectors[pos / max_size].first[pos++ % max_size] = (T)i; 00487 vectors[pos / max_size].first[pos++ % max_size] = (T)j; 00488 vectors[pos / max_size].first[pos++ % max_size] = value; 00489 } 00490 } 00491 } 00492 while (pos < n_elems) // pad with (null_elem, null_elem, null_elem) 00493 { 00494 vectors[pos / max_size].first[pos++ % max_size] = null_elem; 00495 vectors[pos / max_size].first[pos++ % max_size] = null_elem; 00496 vectors[pos / max_size].first[pos++ % max_size] = null_elem; 00497 } 00498 } 00499 00500 template <class T> 00501 void DoubleAccessSparseMatrix<T>::addCompressedVec(T* compressed_vec, int n_elems) 00502 { 00503 if ((n_elems % 3) != 0) PLERROR("n_elems mod 3 must = 0"); 00504 for (int i = 0; i < n_elems; i += 3) 00505 incr((int)compressed_vec[i], (int)compressed_vec[i + 1], compressed_vec[i + 2]); 00506 } 00507 00508 template <class T> 00509 void DoubleAccessSparseMatrix<T>::setCompressedVec(T* compressed_vec, int n_elems) 00510 { 00511 if ((n_elems % 3) != 0) PLERROR("n_elems mod 3 must = 0"); 00512 clear(); 00513 for (int i = 0; i < n_elems; i += 3) 00514 set((int)compressed_vec[i], (int)compressed_vec[i + 1], compressed_vec[i + 2]); 00515 } 00516 00517 template <class T> 00518 T DoubleAccessSparseMatrix<T>::sumOfElements() 00519 { 00520 T sum = 0; 00521 if (mode == ROW_WISE) 00522 { 00523 for (int i = 0; i < height; i++) 00524 { 00525 map<int, T>& row_i = rows[i]; 00526 for (typename map<int, T>::iterator it = row_i.begin(); it != row_i.end(); ++it) 00527 sum += it->second; 00528 } 00529 } else if (mode == COLUMN_WISE) 00530 { 00531 for (int j = 0; j < width; j++) 00532 { 00533 map<int, T>& col_j = cols[j]; 00534 for (typename map<int, T>::iterator it = col_j.begin(); it != col_j.end(); ++it) 00535 sum += it->second; 00536 } 00537 } 00538 return sum; 00539 } 00540 00541 template <class T> 00542 void DoubleAccessSparseMatrix<T>::setDoubleAccessible(bool da) 00543 { 00544 if (double_access != da) 00545 { 00546 double_access = da; 00547 if (!double_access) 00548 { 00549 if (mode == ROW_WISE) 00550 cols.clear(); 00551 else if (mode == COLUMN_WISE) 00552 rows.clear(); 00553 } else 00554 { 00555 if (mode == ROW_WISE) 00556 { 00557 cols.resize(width); 00558 for (int i = 0; i < height; i++) 00559 { 00560 map<int, T>& row_i = rows[i]; 00561 for (typename map<int, T>::iterator it = row_i.begin(); it != row_i.end(); ++it) 00562 { 00563 int j = it->first; 00564 T value = it->second; 00565 set(i, j, value); 00566 } 00567 } 00568 } else if (mode == COLUMN_WISE) 00569 { 00570 rows.resize(height); 00571 for (int j = 0; j < width; j++) 00572 { 00573 map<int, T>& col_j = cols[j]; 00574 for (typename map<int, T>::iterator it = col_j.begin(); it != col_j.end(); ++it) 00575 { 00576 int i = it->first; 00577 T value = it->second; 00578 set(i, j, value); 00579 } 00580 } 00581 } 00582 } 00583 } 00584 } 00585 00586 template <class T> 00587 void DoubleAccessSparseMatrix<T>::setMode(int new_mode) 00588 { 00589 if (mode != ROW_WISE && mode != COLUMN_WISE) PLERROR("mode must be either row-wise or column-wise"); 00590 00591 if (mode != new_mode) 00592 { 00593 mode = new_mode; 00594 if (mode == ROW_WISE && !double_access) 00595 { 00596 rows.resize(height); 00597 for (int j = 0; j < width; j++) 00598 { 00599 map<int, T>& col_j = cols[j]; 00600 for (typename map<int, T>::iterator it = col_j.begin(); it != col_j.end(); ++it) 00601 { 00602 int i = it->first; 00603 T value = it->second; 00604 set(i, j, value); 00605 } 00606 } 00607 cols.clear(); 00608 } else if (mode == COLUMN_WISE && !double_access) 00609 { 00610 cols.resize(width); 00611 for (int i = 0; i < height; i++) 00612 { 00613 map<int, T>& row_i = rows[i]; 00614 for (typename map<int, T>::iterator it = row_i.begin(); it != row_i.end(); ++it) 00615 { 00616 int j = it->first; 00617 T value = it->second; 00618 set(i, j, value); 00619 } 00620 } 00621 rows.clear(); 00622 } 00623 } 00624 } 00625 00626 template <class T> 00627 void DoubleAccessSparseMatrix<T>::write(PStream& out) const 00628 { 00629 string class_name = getClassName(); 00630 switch(out.outmode) 00631 { 00632 case PStream::raw_ascii : 00633 case PStream::pretty_ascii : 00634 PLERROR("raw/pretty_ascii write not implemented in %s", class_name.c_str()); 00635 break; 00636 case PStream::raw_binary : 00637 PLERROR("raw_binary write not implemented in %s", class_name.c_str()); 00638 break; 00639 case PStream::plearn_binary : 00640 case PStream::plearn_ascii : 00641 out.write(class_name + "("); 00642 out << rows; 00643 out << cols; 00644 out << name; 00645 out << mode; 00646 out << double_access; 00647 out << height; 00648 out << width; 00649 out << null_elem; 00650 out.write(")\n"); 00651 break; 00652 default: 00653 PLERROR("unknown outmode in %s::write(PStream& out)", class_name.c_str()); 00654 break; 00655 } 00656 } 00657 00658 template <class T> 00659 void DoubleAccessSparseMatrix<T>::read(PStream& in) 00660 { 00661 string class_name = getClassName(); 00662 switch (in.inmode) 00663 { 00664 case PStream::raw_ascii : 00665 PLERROR("raw_ascii read not implemented in %s", class_name.c_str()); 00666 break; 00667 case PStream::raw_binary : 00668 PLERROR("raw_binary read not implemented in %s", class_name.c_str()); 00669 break; 00670 case PStream::plearn_ascii : 00671 case PStream::plearn_binary : 00672 { 00673 in.skipBlanksAndCommentsAndSeparators(); 00674 string word(class_name.size() + 1, ' '); 00675 for (unsigned int i = 0; i < class_name.size() + 1; i++) 00676 in.get(word[i]); 00677 if (word != class_name + "(") 00678 PLERROR("in %s::(PStream& in), '%s' is not a proper header", class_name.c_str(), word.c_str()); 00679 in.skipBlanksAndCommentsAndSeparators(); 00680 in >> rows; 00681 in.skipBlanksAndCommentsAndSeparators(); 00682 in >> cols; 00683 in.skipBlanksAndCommentsAndSeparators(); 00684 in >> name; 00685 in.skipBlanksAndCommentsAndSeparators(); 00686 in >> mode; 00687 in.skipBlanksAndCommentsAndSeparators(); 00688 in >> double_access; 00689 in.skipBlanksAndCommentsAndSeparators(); 00690 in >> height; 00691 in.skipBlanksAndCommentsAndSeparators(); 00692 in >> width; 00693 in.skipBlanksAndCommentsAndSeparators(); 00694 in >> null_elem; 00695 in.skipBlanksAndCommentsAndSeparators(); 00696 int c = in.get(); 00697 if(c != ')') 00698 PLERROR("in %s::(PStream& in), expected a closing parenthesis, found '%c'", class_name.c_str(), c); 00699 } 00700 break; 00701 default: 00702 PLERROR("unknown inmode in %s::write(PStream& out)", class_name.c_str()); 00703 break; 00704 } 00705 } 00706 00707 } // end of namespace PLearn

Generated on Tue Aug 17 15:51:40 2004 for PLearn by doxygen 1.3.7