PLearn 0.1
ProcessSymbolicSequenceVMatrix.cc
Go to the documentation of this file.
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 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines