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

AsciiVMatrix.cc

Go to the documentation of this file.
00001 // -*- C++ -*- 00002 00003 // AsciiVMatrix.cc 00004 // 00005 // Copyright (C) 2003 Rejean Ducharme, Pascal Vincent 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 00035 /* ******************************************************* 00036 * $Id: AsciiVMatrix.cc,v 1.14 2004/07/08 15:10:09 tihocan Exp $ 00037 ******************************************************* */ 00038 00040 #include "AsciiVMatrix.h" 00041 00042 namespace PLearn { 00043 using namespace std; 00044 00045 00046 PLEARN_IMPLEMENT_OBJECT(AsciiVMatrix, "ONE LINE DESCR", "AsciiVMatrix implements a file in ascii format"); 00047 00048 AsciiVMatrix::AsciiVMatrix() 00049 :file(0), readwritemode(false), newfile(true), 00050 rewrite_length(true) 00051 {} 00052 00053 AsciiVMatrix::AsciiVMatrix(const string& fname, bool readwrite) 00054 :filename(fname), file(0), readwritemode(readwrite), newfile(false), 00055 rewrite_length(true) 00056 { 00057 build(); 00058 } 00059 00060 AsciiVMatrix::AsciiVMatrix(const string& fname, int the_width, 00061 const TVec<string>& the_fieldnames, 00062 const string& comment) 00063 :inherited(0,the_width), filename(fname), file(0), 00064 readwritemode(true), newfile(true), rewrite_length(true) 00065 { 00066 inherited::build(); 00067 00068 if (isfile(filename)) 00069 PLERROR("In AsciiVMatrix constructor: filename %s already exists",filename.c_str()); 00070 file = new fstream(); 00071 file->open(filename.c_str(), fstream::in | fstream::out | fstream::trunc); 00072 if (!file->is_open()) 00073 PLERROR("In AsciiVMatrix constructor: could not open file %s for reading",filename.c_str()); 00074 00075 *file << "#size: "; 00076 vmatlength_pos = file->tellp(); 00077 length_max = 9999999; // = 10 000 000 - 1 00078 *file << "0 " << width() << " " << endl; 00079 00080 00081 if(the_fieldnames.length()>0) 00082 { 00083 if(the_fieldnames.length()!=the_width) 00084 PLERROR("In AsciiVMatrix constructor: number of given fieldnames (%d) differs from given width (%d)", 00085 the_fieldnames.length(), the_width); 00086 *file << "#: "; 00087 for(int k=0; k<the_width; k++) 00088 { 00089 string field_k = space_to_underscore(the_fieldnames[k]); 00090 declareField(k, field_k); 00091 *file << field_k << ' '; 00092 } 00093 *file << endl; 00094 } 00095 00096 if(comment!="") 00097 { 00098 if(comment[0]!='#') 00099 PLERROR("In AsciiVMatrix constructor: comment must start with a #"); 00100 *file << comment; 00101 if(comment[comment.length()-1]!='\n') 00102 *file << endl; 00103 } 00104 00105 } 00106 00107 void AsciiVMatrix::build() 00108 { 00109 inherited::build(); 00110 build_(); 00111 } 00112 00113 void AsciiVMatrix::build_() 00114 { 00115 //setMtime(mtime(filename)); 00116 00117 if(!newfile) // open old file 00118 { 00119 if (!isfile(filename)) 00120 PLERROR("In AsciiVMatrix constructor (with specified width), filename %s does not exists",filename.c_str()); 00121 file = new fstream(); 00122 file->open(filename.c_str(), fstream::in | fstream::out); 00123 if (!file->is_open()) 00124 PLERROR("In AsciiVMatrix constructor, could not open file %s for reading",filename.c_str()); 00125 00126 // read the matrix in old or new format 00127 int length = -1; 00128 int width = -1; 00129 bool could_be_old_amat = true; 00130 file->seekg(0,fstream::beg); 00131 *file >> ws; 00132 string line; 00133 while (file->peek()=='#') 00134 { 00135 streampos old_pos = file->tellg(); 00136 getline(*file, line); 00137 could_be_old_amat = false; 00138 size_t pos=line.find(":"); 00139 if (pos!=string::npos) 00140 { 00141 string sub=line.substr(0,pos); 00142 if (sub=="#size") // we've found the dimension specification line 00143 { 00144 string siz=removeblanks((line.substr(pos)).substr(1)); 00145 vector<string> dim = split(siz," "); 00146 if (dim.size()!=2) PLERROR("I need exactly 2 dimensions for matrix"); 00147 length = toint(dim[0]); 00148 width = toint(dim[1]); 00149 00150 // we set vmatlength_pos 00151 streampos current_pos = file->tellg(); 00152 file->seekg(old_pos); 00153 char c = file->get(); 00154 while (c != ':') 00155 { 00156 c = file->get(); 00157 } 00158 c = file->get(); 00159 vmatlength_pos = file->tellp(); 00160 file->seekg(current_pos); 00161 00162 // we set length_max 00163 int width_ndigits = (int)log(real(width)) + 1; 00164 string remain = removenewline(line.substr(pos+1)); 00165 int length_ndigits = (int)remain.length() - width_ndigits - 1; 00166 length_max = (int)pow(10.0,double(length_ndigits)) - 1; 00167 } 00168 } 00169 *file >> ws; 00170 } 00171 00172 if (length==-1) // still looking for size info... 00173 { 00174 string line; 00175 getNextNonBlankLine(*file,line); 00176 int nfields1 = (int)split(line).size(); 00177 getNextNonBlankLine(*file,line); 00178 if (line=="") // only one line, no length nor width info 00179 { 00180 length=1; 00181 width=nfields1; 00182 rewrite_length = false; 00183 could_be_old_amat = false; 00184 } 00185 int nfields2 = (int)split(line).size(); 00186 int guesslength = countNonBlankLinesOfFile(filename); 00187 real a, b; 00188 if (could_be_old_amat && nfields1==2) // could be an old .amat with first 2 numbers being length width 00189 { 00190 file->seekg(0,fstream::beg); 00191 file->clear(); 00192 vmatlength_pos = file->tellp(); 00193 *file >> a >> b; 00194 if (guesslength == int(a)+1 && real(int(a))==a && real(int(b))==b && a>0 && b>0 && int(b)==nfields2) // it's clearly an old .amat 00195 { 00196 length = int(a); 00197 width = int(b); 00198 00199 file->seekg(vmatlength_pos); 00200 getline(*file, line); 00201 int width_ndigits = (int)log(real(width)) + 1; 00202 int max_length_ndigits = (int)line.length() - width_ndigits - 1; 00203 length_max = (int)pow(10.0,double(max_length_ndigits)) - 1; 00204 } 00205 } 00206 00207 if (length==-1) // still don't know size info... 00208 { 00209 if (nfields1==nfields2) // looks like a plain ascii file 00210 { 00211 rewrite_length = false; 00212 length=guesslength; 00213 if (width!=-1 && width!=nfields1) 00214 { 00215 PLWARNING("In AsciiVMatrix: Number of fieldnames and width mismatch in file %s.", filename.c_str()); 00216 } 00217 width = nfields1; 00218 } 00219 else 00220 PLERROR("In AsciiVMatrix: trying to load but couldn't determine file format automatically for %s",filename.c_str()); 00221 } 00222 } 00223 00224 length_ = length; 00225 width_ = width; 00226 00227 // build the vector of position of the begining of the lines 00228 file->seekg(0,fstream::beg); 00229 file->clear(); 00230 if (could_be_old_amat && rewrite_length) 00231 { 00232 string line; 00233 getline(*file, line); 00234 } 00235 pos_rows.clear(); 00236 while (!file->eof()) 00237 { 00238 *file >> ws; 00239 if (file->peek()!='#' && file->peek()!=EOF) pos_rows.push_back(file->tellg()); 00240 string line; 00241 getline(*file, line); 00242 } 00243 file->clear(); 00244 if ((int)pos_rows.size() != length) 00245 PLERROR("In AsciiVMatrix: the matrix has not the rigth size"); 00246 } 00247 } 00248 00249 void AsciiVMatrix::getNewRow(int i, const Vec& v) const 00250 { 00251 #ifdef BOUNDCHECK 00252 if(i<0 || i>length()) 00253 PLERROR("In AsciiVMatrix::getNewRow, bad row number %d",i); 00254 if(v.length() != width()) 00255 PLERROR("In AsciiVMatrix::getNewRow, length of v (%d) does not match matrix width (%d)",v.length(),width()); 00256 #endif 00257 00258 file->seekg(pos_rows[i]); 00259 for (int j=0; j<width(); j++) 00260 *file >> v[j]; 00261 } 00262 00263 void AsciiVMatrix::appendRow(Vec v) 00264 { 00265 if(v.length()!=width()) 00266 PLERROR("In AsciiVMatrix::appendRow, length of Vec to append (%d) differs from width of matrix (%d)",v.length(), width()); 00267 00268 if (length() == length_max) 00269 PLERROR("AsciiVMatrix::appendRow aborted: the matrix has reach its maximum length."); 00270 00271 if(!readwritemode) 00272 PLERROR("AsciiVMatrix::appendRow aborted: the vmat was opened in read only format."); 00273 00274 // write the Vec at the end of the file 00275 file->seekp(0,fstream::end); 00276 pos_rows.push_back(file->tellg()); 00277 00278 file->precision(15); 00279 for (int i=0; i<v.length(); i++) 00280 *file << v[i] << ' '; 00281 *file << endl; 00282 00283 // update the length 00284 length_++; 00285 if (rewrite_length) 00286 { 00287 file->seekp(vmatlength_pos); 00288 *file << length() << " " << width(); 00289 } 00290 } 00291 00292 void AsciiVMatrix::put(int i, int j, real value) 00293 { PLERROR("In AsciiVMatrix::put not permitted."); } 00294 void AsciiVMatrix::putSubRow(int i, int j, Vec v) 00295 { PLERROR("In AsciiVMatrix::putSubRow not permitted."); } 00296 void AsciiVMatrix::putRow(int i, Vec v) 00297 { PLERROR("In AsciiVMatrix::putRow not permitted."); } 00298 00299 void AsciiVMatrix::declareOptions(OptionList& ol) 00300 { 00301 declareOption(ol, "filename", &AsciiVMatrix::filename, OptionBase::buildoption, "Filename of the matrix"); 00302 declareOption(ol, "readwritemode", &AsciiVMatrix::readwritemode, OptionBase::buildoption, "Is the file to be opened in read/write mode"); 00303 inherited::declareOptions(ol); 00304 } 00305 00306 AsciiVMatrix::~AsciiVMatrix() 00307 { 00308 if (file) 00309 { 00310 if(file->is_open()) 00311 file->close(); 00312 delete file; 00313 } 00314 } 00315 00316 } // end of namespace PLearn 00317

Generated on Tue Aug 17 15:48:36 2004 for PLearn by doxygen 1.3.7