PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // PLearn (A C++ Machine Learning Library) 00004 // Copyright (C) 1998 Pascal Vincent 00005 // Copyright (C) 1999-2001 Pascal Vincent, Yoshua Bengio, Rejean Ducharme and University of Montreal 00006 // Copyright (C) 2002 Pascal Vincent, Julien Keable, Xavier Saint-Mleux 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 /* ******************************************************* 00038 * $Id: RowBufferedVMatrix.cc 6282 2006-10-11 18:44:09Z tihocan $ 00039 ******************************************************* */ 00040 00041 #include "RowBufferedVMatrix.h" 00042 #include <plearn/math/TMat_maths.h> 00043 00044 namespace PLearn { 00045 using namespace std; 00046 00049 PLEARN_IMPLEMENT_ABSTRACT_OBJECT( 00050 RowBufferedVMatrix, 00051 "Base class for VMatrices keeping the last row(s) in a buffer for faster access.", 00052 "" 00053 ); 00054 00055 RowBufferedVMatrix::RowBufferedVMatrix(int the_length, int the_width, 00056 bool call_build_): 00057 inherited (the_length, the_width, call_build_), 00058 current_row_index (-1), 00059 current_row (the_width), 00060 other_row_index (-1), 00061 other_row (the_width) 00062 { 00063 // Never calling build_() since it is not overridden for this class. 00064 } 00065 00066 RowBufferedVMatrix::RowBufferedVMatrix(bool call_build_): 00067 inherited (call_build_), 00068 current_row_index(-1), 00069 other_row_index (-1) 00070 { 00071 // Never calling build_() since it is not overridden for this class. 00072 } 00073 00074 void RowBufferedVMatrix::invalidateBuffer() const 00075 { 00076 current_row_index = -1; 00077 other_row_index = -1; 00078 } 00079 00080 real RowBufferedVMatrix::get(int i, int j) const 00081 { 00082 if(current_row_index!=i) 00083 { 00084 #ifdef BOUNDCHECK 00085 if (i < 0 || (i >= length() && length() >= 0)) 00086 PLERROR("In RowBufferedVMatrix::get: row index (%d) outside valid range [%d,%d]", i, 0, length_-1); 00087 if (j < 0 || j >= width()) 00088 PLERROR("In RowBufferedVMatrix::get: column index (%d) outside valid range [%d,%d]", j, 0, width_-1); 00089 #endif 00090 current_row.resize(width_); 00091 getNewRow(i, current_row); 00092 current_row_index = i; 00093 } 00094 return current_row[j]; 00095 } 00096 00097 00098 void RowBufferedVMatrix::getRow(int i, Vec v) const { 00099 if (current_row_index != i) { 00100 #ifdef BOUNDCHECK 00101 if (i < 0 || (i >= length() && length() >= 0)) 00102 PLERROR("In RowBufferedVMatrix::getRow: row index (%d) outside valid range [%d,%d]", i, 0, length_-1); 00103 #endif 00104 current_row.resize(width_); 00105 getNewRow(i, current_row); 00106 current_row_index = i; 00107 } 00108 if (width_ > 0) 00109 v.copyFrom(current_row.data(), width_); 00110 } 00111 00112 00113 void RowBufferedVMatrix::getSubRow(int i, int j, Vec v) const 00114 { 00115 if(current_row_index!=i) 00116 { 00117 #ifdef BOUNDCHECK 00118 if ((i < 0 || i >= length()) && length() >= 0) 00119 PLERROR("In RowBufferedVMatrix::getSubRow: row index (%d) outside valid range [%d,%d]", i, 0, length_-1); 00120 if ((j < 0 || j >= width()) && width() >= 0) 00121 PLERROR("In RowBufferedVMatrix::getSubRow: column index (%d) outside valid range [%d,%d]", i, 0, width_-1); 00122 #endif 00123 current_row.resize(width_); 00124 getNewRow(i,current_row); 00125 current_row_index = i; 00126 } 00127 if (v.length() > 0) 00128 v.copyFrom(current_row.data()+j, v.length()); 00129 } 00130 00131 00132 real RowBufferedVMatrix::dot(int i1, int i2, int inputsize) const 00133 { 00134 #ifdef BOUNDCHECK 00135 if (i1 < 0 || (i1 >= length() && length() >= 0)) 00136 PLERROR("In RowBufferedVMatrix::dot: first row index (%d) outside valid range [%d,%d]", i1, 0, length_-1); 00137 if (i2 < 0 || (i2 >= length() && length() >= 0)) 00138 PLERROR("In RowBufferedVMatrix::dot: second row index (%d) outside valid range [%d,%d]", i2, 0, length_-1); 00139 #endif 00140 int w = width_; 00141 current_row.resize(w); 00142 other_row.resize(w); 00143 00144 if(i1==current_row_index) 00145 { 00146 if(i2==i1) 00147 return pownorm(current_row.subVec(0,inputsize)); 00148 if(i2!=other_row_index) 00149 { 00150 getNewRow(i2,other_row); 00151 other_row_index = i2; 00152 } 00153 } 00154 else if(i1==other_row_index) 00155 { 00156 if(i2==i1) 00157 return pownorm(other_row.subVec(0,inputsize)); 00158 if(i2!=current_row_index) 00159 { 00160 getNewRow(i2,current_row); 00161 current_row_index = i2; 00162 } 00163 } 00164 else // i1 not cached 00165 { 00166 if(i2==current_row_index) 00167 { 00168 getNewRow(i1,other_row); 00169 other_row_index = i1; 00170 } 00171 else if(i2==other_row_index) 00172 { 00173 getNewRow(i1,current_row); 00174 current_row_index = i1; 00175 } 00176 else // neither i1 nor i2 are cached 00177 { 00178 getNewRow(i1,current_row); 00179 getNewRow(i2,other_row); 00180 current_row_index = i1; 00181 other_row_index = i2; 00182 } 00183 } 00184 return PLearn::dot(current_row.subVec(0,inputsize), other_row.subVec(0,inputsize)); 00185 } 00186 00188 // dot // 00190 real RowBufferedVMatrix::dot(int i, const Vec& v) const 00191 { 00192 if(i!=current_row_index) 00193 { 00194 #ifdef BOUNDCHECK 00195 if (i < 0 || i >= length()) 00196 PLERROR("In RowBufferedVMatrix::dot: row index (%d) outside valid range [%d,%d]", i, 0, length_-1); 00197 #endif 00198 current_row.resize(width_); 00199 getNewRow(i,current_row); 00200 current_row_index = i; 00201 } 00202 return PLearn::dot(current_row.subVec(0,v.length()),v); 00203 } 00204 00206 // makeDeepCopyFromShallowCopy // 00208 void RowBufferedVMatrix::makeDeepCopyFromShallowCopy(CopiesMap& copies) { 00209 inherited::makeDeepCopyFromShallowCopy(copies); 00210 deepCopyField(current_row, copies); 00211 deepCopyField(other_row, copies); 00212 } 00213 00214 } // end of namespace PLearn 00215 00216 00217 /* 00218 Local Variables: 00219 mode:c++ 00220 c-basic-offset:4 00221 c-file-style:"stroustrup" 00222 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00223 indent-tabs-mode:nil 00224 fill-column:79 00225 End: 00226 */ 00227 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :