PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // ProcessSymbolicSequenceVMatrix.cc 00004 // 00005 // Copyright (C) 2004 Hugo Larochelle 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: ProcessSymbolicSequenceVMatrix.cc 8617 2008-03-03 17:45:54Z nouiz $ 00037 ******************************************************* */ 00038 00039 // Authors: Hugo Larochelle 00040 00044 #include "ProcessSymbolicSequenceVMatrix.h" 00045 #include <plearn/base/tostring.h> 00046 00047 namespace PLearn { 00048 using namespace std; 00049 00050 00051 ProcessSymbolicSequenceVMatrix::ProcessSymbolicSequenceVMatrix(bool call_build_) 00052 : inherited(call_build_), 00053 n_left_context(2), n_right_context(2), 00054 conditions_offset(0), conditions_for_exclusion(1), full_context(true), 00055 put_only_target_attributes(false), use_last_context(true), 00056 exclude_missing_target_tokens(false) 00057 /* ### Initialise all fields to their default value */ 00058 { 00059 if( call_build_ ) 00060 build_(); 00061 } 00062 00063 ProcessSymbolicSequenceVMatrix::ProcessSymbolicSequenceVMatrix(VMat s, 00064 int l_context, 00065 int r_context, 00066 bool call_build_) 00067 : inherited(s, call_build_), 00068 conditions_offset(0), conditions_for_exclusion(1), full_context(true), 00069 use_last_context(true) 00070 /* ### Initialise all fields to their default value */ 00071 { 00072 n_left_context= l_context; 00073 n_right_context = r_context; 00074 if( call_build_ ) 00075 build_(); 00076 } 00077 00078 PLEARN_IMPLEMENT_OBJECT(ProcessSymbolicSequenceVMatrix, 00079 "Takes a VMat of a sequence of symbolic elements and constructs context rows.", 00080 "This VMatrix takes a VMat of a sequence of symbolic elements (corresponding\n" 00081 "to a set of symbolic attributes) and constructs context rows.\n" 00082 "An example of a sequence of elements would be a sequence of words, with\n" 00083 "their lemma form and POS tag\n" 00084 "This sequence is encoded using integers, and is represented by the source\n" 00085 "VMatrix such as each row is an element, and each column is a certain type\n" 00086 "of attribute (e.g. lemma, POS tag, etc.).\n" 00087 "The source VMat string mapping (functions getStringVal(...) and\n" 00088 "getValString(...)) contains the integer/string encoding of the symbolic\n" 00089 "data.\n" 00090 "The context rows can be of fixed length, or constrained by delimiter\n" 00091 "symbols.\n" 00092 "Certain rows can be selected/excluded, and certain elements can be excluded\n" 00093 "of a context according to some conditions on its attributes.\n" 00094 "The conditions are expressed as disjunctions of conjunctions. For example:\n" 00095 "\n" 00096 "[ [ 0 : \"person\", 1 : \"NN\" ] , [ 0 : \"kind\", 2 : \"plural\" ] ]\n" 00097 "\n" 00098 "is equivalent in C++ logic form to:\n" 00099 "\n" 00100 "(fields[0]==\"person\" && fields[1]==\"NN\") ||\n" 00101 " (fields[0]==\"kind\" && fields[2]==\"plural\").\n" 00102 "\n" 00103 "Conditions can be expressed in string or int format. The integer/string\n" 00104 "mapping is used to make the correspondance.\n" 00105 "We call the 'target element' of a context the element around which other\n" 00106 "elements are collected to construct the context.\n" 00107 ); 00108 00109 void ProcessSymbolicSequenceVMatrix::getNewRow(int i, const Vec& v) const 00110 { 00111 if(i<0 || i>=length_) 00112 PLERROR("In SelectAttributeSequenceVMatrix::getNewRow() :\n" 00113 " invalid row acces i=%d for VMatrix(%d,%d)\n", 00114 i,length_,width_); 00115 00116 current_row_i.resize(n_attributes*(max_context_length)); 00117 int cp,target_position; 00118 fill_current_row(i,cp,target_position); 00119 00120 if(current_row_i.length()-cp*n_attributes > 0) 00121 current_row_i.subVec(cp*n_attributes,current_row_i.length()-cp*n_attributes).fill(MISSING_VALUE); 00122 00123 // Seperating input and output fields 00124 00125 for(int t=0; t<current_row_i.length(); t++) 00126 { 00127 if(t%n_attributes < source->inputsize()) 00128 v[t/n_attributes * source->inputsize() + t%n_attributes] = current_row_i[t]; 00129 else 00130 if(put_only_target_attributes) 00131 { 00132 if(t/n_attributes == target_position) 00133 v[max_context_length*source->inputsize() + t%n_attributes - source->inputsize() ] = current_row_i[t]; 00134 } 00135 else 00136 v[max_context_length*source->inputsize() + t/n_attributes * source->targetsize() + t%n_attributes - source->inputsize() ] = current_row_i[t]; 00137 } 00138 00139 return; 00140 } 00141 00142 void ProcessSymbolicSequenceVMatrix::declareOptions(OptionList& ol) 00143 { 00144 // ### Declare all of this object's options here 00145 // ### For the "flags" of each option, you should typically specify 00146 // ### one of OptionBase::buildoption, OptionBase::learntoption or 00147 // ### OptionBase::tuningoption. Another possible flag to be combined with 00148 // ### is OptionBase::nosave 00149 00150 declareOption(ol, "n_left_context", 00151 &ProcessSymbolicSequenceVMatrix::n_left_context, 00152 OptionBase::buildoption, 00153 "Number of elements at the left of (or before) the target" 00154 " element.\n" 00155 "(if < 0, all elements to the left are included until a" 00156 " delimiter is met)\n"); 00157 00158 declareOption(ol, "n_right_context", 00159 &ProcessSymbolicSequenceVMatrix::n_right_context, 00160 OptionBase::buildoption, 00161 "Number of elements at the right of (or after) the target" 00162 " element.\n" 00163 "(if < 0, all elements to the right are included until a" 00164 " delimiter is met)\n"); 00165 00166 declareOption(ol, "conditions_offset", 00167 &ProcessSymbolicSequenceVMatrix::conditions_offset, 00168 OptionBase::buildoption, 00169 "Offset for the position of the element on which conditions" 00170 " are tested\n" 00171 "(default = 0)\n"); 00172 00173 declareOption(ol, "conditions_for_exclusion", 00174 &ProcessSymbolicSequenceVMatrix::conditions_for_exclusion, 00175 OptionBase::buildoption, 00176 "Indication that the specified conditions are for the" 00177 " exclusion (true)\n" 00178 "or inclusion (false) of elements in the VMatrix\n"); 00179 00180 declareOption(ol, "full_context", 00181 &ProcessSymbolicSequenceVMatrix::full_context, 00182 OptionBase::buildoption, 00183 "Indication that ignored elements of context should be" 00184 " replaced by the\n" 00185 "next nearest valid element\n"); 00186 00187 declareOption(ol, "put_only_target_attributes", 00188 &ProcessSymbolicSequenceVMatrix::put_only_target_attributes, 00189 OptionBase::buildoption, 00190 "Indication that the only target fields of the VMatrix rows" 00191 " should be\n" 00192 "the (target) attributes of the context's target element\n"); 00193 00194 declareOption(ol, "use_last_context", 00195 &ProcessSymbolicSequenceVMatrix::use_last_context, 00196 OptionBase::buildoption, 00197 "Indication that the last accessed context should be put in" 00198 " a buffer.\n"); 00199 00200 declareOption(ol, "exclude_missing_target_tokens", 00201 &ProcessSymbolicSequenceVMatrix::exclude_missing_target_tokens, 00202 OptionBase::buildoption, 00203 "Indication to exclude from the VMatrix the context centered\n" 00204 "around a token with missing value target fields.\n"); 00205 00206 00207 00208 declareOption(ol, "conditions", 00209 &ProcessSymbolicSequenceVMatrix::conditions, 00210 OptionBase::buildoption, 00211 "Conditions to be satisfied for the exclusion or inclusion" 00212 " (see\n" 00213 "conditions_for_exclusion) of elements in the VMatrix\n"); 00214 00215 declareOption(ol, "string_conditions", 00216 &ProcessSymbolicSequenceVMatrix::string_conditions, 00217 OptionBase::buildoption, 00218 "Conditions, in string format, to be satisfied for the" 00219 " exclusion or\n" 00220 "inclusion (see conditions_for_exclusion) of elements in the" 00221 " VMatrix\n"); 00222 00223 declareOption(ol, "delimiters", 00224 &ProcessSymbolicSequenceVMatrix::delimiters, 00225 OptionBase::buildoption, 00226 "Delimiters of context\n"); 00227 00228 declareOption(ol, "string_delimiters", 00229 &ProcessSymbolicSequenceVMatrix::string_delimiters, 00230 OptionBase::buildoption, 00231 "Delimiters, in string format, of context\n"); 00232 00233 declareOption(ol, "ignored_context", 00234 &ProcessSymbolicSequenceVMatrix::ignored_context, 00235 OptionBase::buildoption, 00236 "Elements to be ignored in context\n"); 00237 00238 declareOption(ol, "string_ignored_context", 00239 &ProcessSymbolicSequenceVMatrix::string_ignored_context, 00240 OptionBase::buildoption, 00241 "Elements, in string format, to be ignored in context\n"); 00242 00243 // Now call the parent class' declareOptions 00244 inherited::declareOptions(ol); 00245 } 00246 00247 void ProcessSymbolicSequenceVMatrix::build_() 00248 { 00249 00250 if(!source) 00251 PLERROR("In SelectAttributeSequenceVMatrix::build_() : no source" 00252 " defined"); 00253 00254 // defineSizes(source->inputsize(),source->targetsize(),source->weightsize()); pas bon car ecrase declare options 00255 n_attributes = source->width(); 00256 row.resize(n_attributes); 00257 element.resize(n_attributes); 00258 target_element.resize(n_attributes); 00259 max_context_length = 0; 00260 00261 fixed_context = n_left_context >=0 && n_right_context >= 0; 00262 00263 // from string to int format on ... 00264 00265 // conditions 00266 from_string_to_int_format(string_conditions, conditions); 00267 string_conditions.clear(); 00268 string_conditions.resize(0); 00269 00270 // delimiters 00271 from_string_to_int_format(string_delimiters, delimiters); 00272 string_delimiters.clear(); 00273 string_delimiters.resize(0); 00274 00275 // ignored_context 00276 from_string_to_int_format(string_ignored_context, ignored_context); 00277 string_ignored_context.clear(); 00278 string_ignored_context.resize(0); 00279 00280 // gathering information from source VMat 00281 00282 indices.clear(); 00283 indices.resize(0); 00284 int current_context_length = 0; 00285 bool target_contains_missing = false; 00286 PP<ProgressBar> pb = new ProgressBar("Gathering information from source VMat of length " + tostring(source->length()), source->length()); 00287 for(int i=0; i<source->length(); i++) 00288 { 00289 source->getRow(i,row); 00290 00291 if(is_true(delimiters,row)) 00292 { 00293 max_context_length = max_context_length < current_context_length ? current_context_length : max_context_length; 00294 current_context_length = 0; 00295 } 00296 else 00297 { 00298 if(!full_context || !is_true(ignored_context,row)) current_context_length++; 00299 } 00300 00301 // Testing conditions for inclusion/exclusion 00302 00303 if(i + conditions_offset >= 0 && i + conditions_offset < source->length()) 00304 { 00305 source->getRow(i+conditions_offset,row); 00306 if(exclude_missing_target_tokens) 00307 { 00308 target_contains_missing = false; 00309 int ni = source->targetsize()+source->inputsize(); 00310 for(int j=source->inputsize(); j<ni; j++) 00311 if(is_missing(row[j])) 00312 { 00313 target_contains_missing = true; 00314 break; 00315 } 00316 } 00317 00318 if(!exclude_missing_target_tokens || !target_contains_missing) 00319 { 00320 if(is_true(conditions,row)) 00321 { 00322 if(!conditions_for_exclusion) indices.append(i); 00323 } 00324 else 00325 { 00326 if(conditions_for_exclusion) indices.append(i); 00327 } 00328 } 00329 } 00330 pb->update(i+1); 00331 } 00332 00333 max_context_length = max_context_length < current_context_length ? current_context_length : max_context_length; 00334 00335 if(n_left_context >= 0 && n_right_context >= 0) 00336 max_context_length = 1 + n_left_context + n_right_context; 00337 00338 length_ = indices.length(); 00339 width_ = n_attributes*(max_context_length); 00340 00341 if(inputsize_ < 0) inputsize_ = max_context_length * source->inputsize(); 00342 if(targetsize_ < 0 && put_only_target_attributes) targetsize_ = source->targetsize(); 00343 if(targetsize_ < 0 && !put_only_target_attributes) targetsize_ = max_context_length * source->targetsize(); 00344 if(weightsize_ < 0) weightsize_ = source->weightsize(); 00345 if(weightsize_ > 0) PLERROR("In ProcessSymbolicSequenceVMatrix:build_() : does not support weightsize > 0"); 00346 00347 current_row_i.resize(n_attributes*(max_context_length)); 00348 current_target_pos = -1; 00349 current_context_pos.clear(); 00350 lower_bound = 1; 00351 upper_bound = -1; 00352 00353 if(n_left_context < 0) 00354 { 00355 left_context.resize(width_); 00356 left_positions.resize(max_context_length); 00357 } 00358 else 00359 { 00360 left_context.resize(n_attributes*n_left_context); 00361 left_positions.resize(n_left_context); 00362 } 00363 00364 if(n_right_context < 0) 00365 { 00366 right_context.resize(width_); 00367 right_positions.resize(max_context_length); 00368 } 00369 else 00370 { 00371 right_context.resize(n_attributes*n_right_context); 00372 right_positions.resize(n_right_context); 00373 } 00374 00375 if(put_only_target_attributes) 00376 { 00377 width_ = source->inputsize()*max_context_length + source->targetsize(); 00378 } 00379 00380 if(inputsize_+targetsize_ != width_) PLERROR("In ProcessSymbolicSequenceVMatrix:build_() : inputsize_ + targetsize_ != width_"); 00381 00382 00383 // Should we call: 00384 // setMetaInfoFromSource(); // ? 00385 updateMtime(source); 00386 } 00387 00388 void ProcessSymbolicSequenceVMatrix::build() 00389 { 00390 inherited::build(); 00391 build_(); 00392 } 00393 00394 real ProcessSymbolicSequenceVMatrix::getStringVal(int col, const string & str) const 00395 { 00396 if(source) 00397 { 00398 int src_col; 00399 if(col < max_context_length * source->inputsize()) 00400 src_col = col%source->inputsize(); 00401 else 00402 src_col = source->inputsize() + (col-max_context_length * source->inputsize())%source->targetsize(); 00403 return source->getStringVal(src_col,str); 00404 } 00405 00406 return MISSING_VALUE; 00407 } 00408 00409 string ProcessSymbolicSequenceVMatrix::getValString(int col, real val) const 00410 { 00411 if(source) 00412 { 00413 int src_col; 00414 if(col < max_context_length * source->inputsize()) 00415 src_col = col%source->inputsize(); 00416 else 00417 src_col = source->inputsize() + (col-max_context_length * source->inputsize())%source->targetsize(); 00418 return source->getValString(src_col,val); 00419 } 00420 00421 return ""; 00422 } 00423 00424 void ProcessSymbolicSequenceVMatrix::getValues(int row, int col, Vec& values) const 00425 { 00426 if(row < 0 || row >= length_) PLERROR("In ProcessSymbolicSequenceVMatrix::getValues() : invalid row %d, length()=%d", row, length_); 00427 if(col < 0 || col >= width_) PLERROR("In ProcessSymbolicSequenceVMatrix::getValues() : invalid col %d, width()=%d", col, width_); 00428 if(source) 00429 { 00430 int src_col; 00431 if(col < max_context_length * source->inputsize()) 00432 src_col = col%source->inputsize(); 00433 else 00434 src_col = source->inputsize() + (col-max_context_length * source->inputsize())%source->targetsize(); 00435 source->getValues(indices[row],src_col, values); 00436 } 00437 else 00438 values.resize(0); 00439 } 00440 00441 void ProcessSymbolicSequenceVMatrix::getValues(const Vec& input, int col, Vec& values) const 00442 { 00443 if(col < 0 || col >= width_) PLERROR("In ProcessSymbolicSequenceVMatrix::getValues() : invalid col %d, width()=%d", col, width_); 00444 if(source) 00445 { 00446 int sinputsize = source->inputsize(); 00447 int stargetsize = source->targetsize(); 00448 int src_col,this_col; 00449 if(col < max_context_length * sinputsize) 00450 src_col = col%sinputsize; 00451 else 00452 src_col = sinputsize + (col-max_context_length * sinputsize)%stargetsize; 00453 00454 // Fill subinput input part 00455 subinput.resize(sinputsize); 00456 if(col>=inputsize_) 00457 { 00458 if(put_only_target_attributes) 00459 this_col = n_left_context; 00460 else 00461 this_col = (col-inputsize_)/stargetsize; 00462 } 00463 else 00464 this_col = col/sinputsize; 00465 subinput << input.subVec(this_col*sinputsize,sinputsize); 00466 00467 // Fill subinput target part 00468 subinput.resize(sinputsize+stargetsize); 00469 if(!put_only_target_attributes || col == inputsize_ || (col<inputsize_ && col/sinputsize == n_left_context)) 00470 { 00471 if(put_only_target_attributes) 00472 subinput.subVec(sinputsize,stargetsize) << input.subVec(inputsize_,stargetsize); 00473 else 00474 subinput.subVec(sinputsize,stargetsize) << input.subVec(inputsize_+this_col*stargetsize,stargetsize); 00475 00476 } 00477 else 00478 { 00479 subinput.subVec(sinputsize,stargetsize).fill(MISSING_VALUE); 00480 } 00481 source->getValues(subinput,src_col,values); 00482 } 00483 else values.resize(0); 00484 } 00485 00486 PP<Dictionary> ProcessSymbolicSequenceVMatrix::getDictionary(int col) const 00487 { 00488 if(col < 0 || col >= width_) PLERROR("In ProcessSymbolicSequenceVMatrix::getDictionary() : invalid col %d, width()=%d", col, width_); 00489 if(source) 00490 { 00491 int src_col; 00492 if(col < max_context_length * source->inputsize()) 00493 src_col = col%source->inputsize(); 00494 else 00495 src_col = source->inputsize() + (col-max_context_length * source->inputsize())%source->targetsize(); 00496 return source->getDictionary(src_col); 00497 } 00498 return 0; 00499 } 00500 00501 void ProcessSymbolicSequenceVMatrix::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00502 { 00503 inherited::makeDeepCopyFromShallowCopy(copies); 00504 00505 deepCopyField(conditions, copies); 00506 deepCopyField(string_conditions, copies); 00507 deepCopyField(delimiters, copies); 00508 deepCopyField(string_delimiters, copies); 00509 deepCopyField(ignored_context, copies); 00510 deepCopyField(string_ignored_context, copies); 00511 deepCopyField(current_row_i, copies); 00512 deepCopyField(indices, copies); 00513 deepCopyField(left_positions, copies); 00514 deepCopyField(right_positions, copies); 00515 deepCopyField(left_context, copies); 00516 deepCopyField(right_context, copies); 00517 deepCopyField(subinput, copies); 00518 deepCopyField(row, copies); 00519 deepCopyField(element, copies); 00520 deepCopyField(target_element, copies); 00521 } 00522 00523 void ProcessSymbolicSequenceVMatrix::fill_current_row(int i, int& cp, int& target_position) const 00524 { 00525 00526 int target = indices[i]; 00527 00528 // If the target element is a delimiter, do nothing: Hugo: may not be a good thing! 00529 source->getRow(target,target_element); 00530 /* 00531 if(is_true(delimiters,target_element)) 00532 { 00533 v.fill(MISSING_VALUE); 00534 if(use_last_context) 00535 { 00536 current_context_pos.clear(); 00537 current_row_i.fill(MISSING_VALUE); 00538 current_target_pos = -1; 00539 lower_bound = 1; 00540 upper_bound = -1; 00541 } 00542 return; 00543 } 00544 */ 00545 00546 int left_added_elements = 0; 00547 int right_added_elements = 0; 00548 00549 int left_pos = 1; 00550 int right_pos = 1; 00551 int p = 0; 00552 00553 bool to_add = false; 00554 00555 int this_lower_bound = target; 00556 int this_upper_bound = target; 00557 00558 // Left context construction 00559 00560 while(n_left_context < 0 || left_added_elements < n_left_context) 00561 { 00562 to_add = false; 00563 00564 00565 p = target-left_pos; 00566 00567 if(p < 0 || p >= source->length()) 00568 break; 00569 00570 // Verifying if context can be found in last context 00571 if(use_last_context && lower_bound <= p && upper_bound >= p) 00572 { 00573 if(current_context_pos.find(p) != current_context_pos.end()) 00574 { 00575 int position = current_context_pos[p]; 00576 element = current_row_i.subVec(n_attributes*position,n_attributes); 00577 if(!is_true(ignored_context,element)) 00578 { 00579 to_add = true; 00580 } 00581 } 00582 else 00583 { 00584 left_pos++; 00585 continue; 00586 } 00587 } // If not, fetch element in source VMat 00588 else 00589 { 00590 source->getRow(p,element); 00591 if(!is_true(ignored_context,element)) 00592 to_add = true; 00593 } 00594 00595 if(is_true(delimiters,element)) break; 00596 00597 if(to_add) 00598 { 00599 left_context.subVec(n_attributes*left_added_elements,n_attributes) << element; 00600 if(use_last_context) left_positions[left_added_elements] = p; 00601 this_lower_bound = p; 00602 left_added_elements++; 00603 } 00604 else 00605 if(!full_context) 00606 { 00607 left_context.subVec(n_attributes*left_added_elements,n_attributes).fill(MISSING_VALUE); 00608 if(use_last_context) left_positions[left_added_elements] = p; 00609 this_lower_bound = p; 00610 left_added_elements++; 00611 } 00612 00613 left_pos++; 00614 } 00615 00616 // Right context construction 00617 00618 while(n_right_context < 0 || right_added_elements < n_right_context) 00619 { 00620 to_add = false; 00621 00622 p = target+right_pos; 00623 00624 if(p < 0 || p >= source->length()) 00625 break; 00626 00627 // Verifying if context can be found in last context 00628 if(use_last_context && lower_bound <= p && upper_bound >= p) 00629 { 00630 if(current_context_pos.find(p) != current_context_pos.end()) 00631 { 00632 int position = current_context_pos[p]; 00633 element = current_row_i.subVec(n_attributes*position,n_attributes); 00634 if(!is_true(ignored_context,element)) 00635 { 00636 to_add = true; 00637 } 00638 } 00639 else 00640 { 00641 right_pos++; 00642 continue; 00643 } 00644 } // If not, fetch element in source VMat 00645 else 00646 { 00647 source->getRow(p,element); 00648 if(!is_true(ignored_context,element)) 00649 to_add = true; 00650 } 00651 00652 if(is_true(delimiters,element)) break; 00653 00654 if(to_add) 00655 { 00656 right_context.subVec(n_attributes*right_added_elements,n_attributes) << element; 00657 if(use_last_context) right_positions[right_added_elements] = p; 00658 this_upper_bound = p; 00659 right_added_elements++; 00660 } 00661 else 00662 if(!full_context) 00663 { 00664 right_context.subVec(n_attributes*right_added_elements,n_attributes).fill(MISSING_VALUE); 00665 if(use_last_context) right_positions[right_added_elements] = p; 00666 this_upper_bound = p; 00667 right_added_elements++; 00668 } 00669 00670 right_pos++; 00671 } 00672 00673 current_context_pos.clear(); 00674 current_target_pos = -1; 00675 lower_bound = this_lower_bound; 00676 upper_bound = this_upper_bound; 00677 //current_row_i.fill(MISSING_VALUES); 00678 00679 // Constructing complete row 00680 00681 cp = 0; 00682 00683 if(fixed_context) // Adding missing value, for the case where the context is of fixed length 00684 if(n_left_context-left_added_elements>0) 00685 { 00686 current_row_i.subVec(cp*n_attributes,n_attributes*(n_left_context-left_added_elements)).fill(MISSING_VALUE); 00687 cp = n_left_context-left_added_elements; 00688 } 00689 00690 // adding left context 00691 00692 int temp = left_added_elements; 00693 00694 while(temp > 0) 00695 { 00696 temp--; 00697 current_row_i.subVec(cp*n_attributes,n_attributes) << left_context.subVec(temp*n_attributes,n_attributes); 00698 if(use_last_context) current_context_pos[(int)left_positions[temp]] = cp; 00699 cp++; 00700 } 00701 00702 // adding target element 00703 target_position = cp; 00704 current_row_i.subVec(cp*n_attributes,n_attributes) << target_element; 00705 if(use_last_context) 00706 { 00707 current_context_pos[target] = cp; 00708 current_target_pos = cp; 00709 } 00710 cp++; 00711 00712 // adding right context 00713 00714 int r=0; 00715 while(r<right_added_elements) 00716 { 00717 current_row_i.subVec(cp*n_attributes,n_attributes) << right_context.subVec(r*n_attributes,n_attributes); 00718 if(use_last_context) current_context_pos[(int)right_positions[r]] = cp; 00719 r++; 00720 cp++; 00721 } 00722 00723 if(fixed_context && current_row_i.length()-cp*n_attributes > 0) 00724 { 00725 current_row_i.subVec(cp*n_attributes,current_row_i.length()-cp*n_attributes).fill(MISSING_VALUE); 00726 cp = current_row_i.length()/n_attributes; 00727 } 00728 } 00729 00730 00731 void ProcessSymbolicSequenceVMatrix::getExample(int i, Vec& input, Vec& target, real& weight) 00732 { 00733 if(i<0 || i>=length_) PLERROR("In SelectAttributeSequenceVMatrix::getExample() : invalid row acces i=%d for VMatrix(%d,%d)",i,length_,width_); 00734 00735 int target_position,cp; 00736 fill_current_row(i,cp,target_position); 00737 00738 // Seperating input and output fields 00739 input.resize(cp*source->inputsize()); 00740 target.resize(put_only_target_attributes ? source->targetsize() : cp*source->targetsize()); 00741 if(weightsize_ == 0) 00742 weight = 1; 00743 else 00744 PLERROR("In ProcessSymbolicSequenceVMatrix::getExample(): weighsize() > 0 not implemented"); 00745 for(int t=0; t<cp*n_attributes; t++) 00746 { 00747 if(t%n_attributes < source->inputsize()) 00748 input[t/n_attributes * source->inputsize() + t%n_attributes] = current_row_i[t]; 00749 else 00750 if(put_only_target_attributes) 00751 { 00752 if(t/n_attributes == target_position) 00753 target[t%n_attributes - source->inputsize() ] = current_row_i[t]; 00754 } 00755 else 00756 target[t/n_attributes * source->targetsize() + t%n_attributes - source->inputsize() ] = current_row_i[t]; 00757 } 00758 00759 if(fixed_context) 00760 { 00761 // Verify if inputsize and targetsize were redefined 00762 if(inputsize_ > input.length()) 00763 { 00764 input.resize(inputsize_); 00765 int it = 0; 00766 for(int t=cp*source->inputsize(); t<inputsize_; t++) 00767 input[t] = target[it++]; 00768 for(int t=0; t<targetsize_; t++) 00769 target[t] = target[it++]; 00770 target.resize(targetsize_); 00771 } 00772 else if(targetsize() > target.length()) 00773 { 00774 target.resize(targetsize_); 00775 int it = cp*source->inputsize()-inputsize_; 00776 for(int t=0; it<targetsize_; t++) 00777 target[it++] = target[t]; 00778 it = inputsize_; 00779 for(int t=0; it<input.length(); t++) 00780 target[t] = input[it++]; 00781 input.resize(inputsize_); 00782 } 00783 } 00784 00785 return; 00786 } 00787 00788 } // end of namespace PLearn 00789 00790 00791 /* 00792 Local Variables: 00793 mode:c++ 00794 c-basic-offset:4 00795 c-file-style:"stroustrup" 00796 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00797 indent-tabs-mode:nil 00798 fill-column:79 00799 End: 00800 */ 00801 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :