PLearn 0.1
MissingInstructionVMatrix.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // MissingInstructionVMatrix.cc
00004 //
00005 // Copyright (C) 2007 Frederic Bastien
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 // Authors: Frederic Bastien
00036 
00040 #include "MissingInstructionVMatrix.h"
00041 
00042 namespace PLearn {
00043 using namespace std;
00044 
00045 
00046 PLEARN_IMPLEMENT_OBJECT(
00047     MissingInstructionVMatrix,
00048     "Transform some value as missing following received instruction",
00049     "NO HELP"
00050     );
00051 
00052 MissingInstructionVMatrix::MissingInstructionVMatrix():
00053     default_instruction(""),
00054     missing_field_error(true)
00055 /* ### Initialize all fields to their default value */
00056 {
00057     // ...
00058 
00059     // ### You may (or not) want to call build_() to finish building the object
00060     // ### (doing so assumes the parent classes' build_() have been called too
00061     // ### in the parent classes' constructors, something that you must ensure)
00062 }
00063 
00064 void MissingInstructionVMatrix::getNewRow(int i, const Vec& v) const
00065 {
00066     // ...
00067     source->getRow(i,tmp2);
00068     for (int col = 0,merge_col = 0; col < source->width(); col++)
00069     {
00070         if (ins[col] == "skip") continue;
00071         else if (ins[col] == "as_is")
00072         {
00073             v[merge_col] = tmp2[col];
00074         }
00075         else if (ins[col] == "zero_is_missing")
00076         {
00077             if (tmp2[col] == 0.0) v[merge_col] = MISSING_VALUE;
00078             else v[merge_col] = tmp2[col];
00079         }
00080         else if (ins[col] == "zero_or_neg_is_missing")
00081         {
00082             if (tmp2[col] <= 0.0) v[merge_col] = MISSING_VALUE;
00083             else v[merge_col] = tmp2[col];
00084         }
00085         else if (ins[col] == "2436935_is_missing")
00086         {
00087             if (tmp2[col] == 2436935.0) v[merge_col] = MISSING_VALUE;
00088             else v[merge_col] = tmp2[col];
00089         }
00090         else if (ins[col] == "present")
00091         {
00092             if (is_missing(tmp2[col])) v[merge_col] = 0.0;
00093             else v[merge_col] = 1.0;
00094         }
00095         merge_col +=1;
00096     }
00097 }
00098 
00099 void MissingInstructionVMatrix::declareOptions(OptionList& ol)
00100 {
00101     // ### Declare all of this object's options here.
00102     // ### For the "flags" of each option, you should typically specify
00103     // ### one of OptionBase::buildoption, OptionBase::learntoption or
00104     // ### OptionBase::tuningoption. If you don't provide one of these three,
00105     // ### this option will be ignored when loading values from a script.
00106     // ### You can also combine flags, for example with OptionBase::nosave:
00107     // ### (OptionBase::buildoption | OptionBase::nosave)
00108 
00109     // ### ex:
00110     // declareOption(ol, "myoption", &MissingInstructionVMatrix::myoption,
00111     //               OptionBase::buildoption,
00112     //               "Help text describing this option");
00113     // ...
00114 
00115     // Now call the parent class' declareOptions
00116     inherited::declareOptions(ol);
00117     declareOption(ol, "missing_instructions", &MissingInstructionVMatrix::missing_instructions,
00118                   OptionBase::buildoption,
00119                   "The variable missing regeneration instructions in the form of pairs field : instruction.\n"
00120                   "Supported instructions are skip, as_is, zero_is_missing, zero_or_neg_is_missing, 2436935_is_missing(01JAN1960 in julian day), jdate_is_missing(idem as 2436935_is_missing), present.\n"
00121                   "If the instruction fieldname end with '*' we will extend it to all the source matrix fieldname that match the regex.\n"
00122                   "No other regex are supported");
00123     declareOption(ol, "default_instruction",
00124                   &MissingInstructionVMatrix::default_instruction,
00125                   OptionBase::buildoption,
00126                   "If some field in the source matrix have no instruction," 
00127                   " we will use this instruction. We will warn about field"
00128                   " with empty instruction then will stop.");
00129    declareOption(ol, "missing_field_error",
00130                   &MissingInstructionVMatrix::missing_field_error ,
00131                   OptionBase::buildoption,
00132                  "If true will generate an error if some instruction reference missing field" );
00133 }
00134 
00135 void MissingInstructionVMatrix::build_()
00136 {
00137     // ### This method should do the real building of the object,
00138     // ### according to set 'options', in *any* situation.
00139     // ### Typical situations include:
00140     // ###  - Initial building of an object from a few user-specified options
00141     // ###  - Building of a "reloaded" object: i.e. from the complete set of
00142     // ###    all serialised options.
00143     // ###  - Updating or "re-building" of an object after a few "tuning"
00144     // ###    options have been modified.
00145     // ### You should assume that the parent class' build_() has already been
00146     // ### called.
00147     updateMtime(source);
00148     length_ = source->length();
00149     ins.resize(source->width());
00150     tmp2.resize(source->width());
00151     TVec<string> source_names = source->fieldNames();
00152 
00153     //set default instruction
00154     ins.fill(default_instruction);
00155 
00156     int skip_instruction_input = 0;
00157     int skip_instruction_target = 0;
00158     int skip_instruction_weight = 0;
00159     int skip_instruction_extra = 0;
00160     if(default_instruction!="skip")
00161         width_=source->width();
00162     else{
00163         width_=missing_instructions.size();
00164         PLWARNING("MissingInstructionVMatrix::build_() - "
00165                   "we suppose that the default instruction apply only to input fields");
00166         skip_instruction_input = source->width() - missing_instructions.size();
00167     }
00168     TVec< pair<string, string> > not_used_spec;
00169     for (int ins_col = 0; ins_col < missing_instructions.size(); ins_col++)
00170     {
00171         int source_col = 0;
00172         pair<string, string> mis_ins=missing_instructions[ins_col];
00173         for (source_col = 0; source_col < source->width(); source_col++)
00174         {
00175             if (mis_ins.first == source_names[source_col]) break;
00176         }
00177         if (source_col >= source->width() && 
00178             mis_ins.first[mis_ins.first.size()-1]=='*') {
00179             string sub_name=mis_ins.first.substr(0,mis_ins.first.size()-1);
00180             for (source_col = 0; source_col < source->width(); source_col++)
00181             {
00182                 if (string_begins_with(source_names[source_col],sub_name)){
00183                     missing_instructions.append(
00184                         make_pair(source_names[source_col],mis_ins.second));
00185                 } 
00186             }
00187             continue;
00188         } else if (source_col >= source->width()) 
00189         {
00190             if(missing_instructions[ins_col].second!="skip"){
00191                 //if the instruction is skip, we don't care that it is missing in the source!
00192                 not_used_spec.append(missing_instructions[ins_col]);
00193             }
00194             continue;
00195         }
00196         if (missing_instructions[ins_col].second == "skip")
00197             ins[source_col] = "skip";
00198         else if (missing_instructions[ins_col].second == "as_is")
00199             ins[source_col] = "as_is";
00200         else if (missing_instructions[ins_col].second == "zero_is_missing")
00201             ins[source_col] = "zero_is_missing";
00202         else if (missing_instructions[ins_col].second == "zero_or_neg_is_missing")
00203             ins[source_col] = "zero_or_neg_is_missing";
00204         else if (missing_instructions[ins_col].second == "2436935_is_missing"
00205                  || missing_instructions[ins_col].second == "jdate_is_missing")
00206             ins[source_col] = "2436935_is_missing";
00207         else if (missing_instructions[ins_col].second == "present")
00208             ins[source_col] = "present";
00209         else if (missing_instructions[ins_col].second.empty())
00210             PLWARNING("In MissingInstructionVMatrix::build_() -"
00211                       " merge instruction empty for field '%s',"
00212                       " we keep the previous instruction who could be"
00213                       " the default_instruction",
00214                       (missing_instructions[source_col].first).c_str());
00215         else PLERROR("In MissingInstructionVMatrix::build_() -"
00216                      " unsupported merge instruction: '%s'", 
00217                      (missing_instructions[ins_col].second).c_str());
00218         if (ins[source_col] == "skip"){
00219             if(source_col<source->inputsize())
00220                 skip_instruction_input++;
00221             else if(source_col<(source->inputsize() + source->targetsize()))
00222                 skip_instruction_target++;
00223             else if (source_col<(source->inputsize() + source->targetsize()
00224                                  + source->weightsize()))
00225                 skip_instruction_weight++;
00226             else skip_instruction_extra++;
00227         }
00228     }
00229     if(not_used_spec.length()>0){
00230         TVec< pair<string, string> >  m;
00231         PLWARNING("In MissingInstructionVMatrix::build_() -"
00232                   " There is %d instructions where the field are not in the source: %s"
00233                   ,not_used_spec.length(),tostring(not_used_spec).c_str());
00234 
00235     }
00236     setMetaInfoFromSource();
00237     defineSizes(source->inputsize() - skip_instruction_input,
00238                 source->targetsize() - skip_instruction_target,
00239                 source->weightsize() - skip_instruction_weight,
00240                 source->extrasize() - skip_instruction_extra);
00241     width_ = inputsize_ + targetsize_ + weightsize_ + extrasize_;
00242     int missing_instruction = 0;
00243     for (int col = 0; col < source->width(); col++)
00244     {
00245         if(ins[col].empty())
00246         {
00247             PLWARNING("In MissingInstructionVMatrix::build_ -"
00248                       " their is no instruction for the field '%s'",
00249                     source_names[col].c_str());
00250             missing_instruction++;
00251         }   
00252     }
00253     if(missing_instruction)
00254         PLERROR("In MissingInstructionVMatrix::build_ -"
00255                 " Their have been %d field in the source"
00256                 " matrix that have no instruction. Do you want"
00257                 " to set the default_instruction option?",missing_instruction);
00258     if(not_used_spec.length()>0 && missing_field_error)
00259         PLERROR("In MissingInstructionVMatrix::build_ - Their have been %d"
00260                 " instruction that have no correcponding field in the"
00261                 " source matrix",not_used_spec.length());
00262 
00263     // Copy the appropriate VMFields
00264     fieldinfos.resize(width());
00265     if (source->getFieldInfos().size() > 0) {
00266         for (int source_col=0,merge_col=0; source_col<source->width(); ++source_col) {
00267             if(ins[source_col]!="skip"){
00268                 fieldinfos[merge_col] = source->getFieldInfos(source_col);
00269                 merge_col++;
00270             }
00271         }
00272     }
00273 
00274 }
00275 
00276 // ### Nothing to add here, simply calls build_
00277 void MissingInstructionVMatrix::build()
00278 {
00279     inherited::build();
00280     build_();
00281 }
00282 
00283 void MissingInstructionVMatrix::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00284 {
00285     inherited::makeDeepCopyFromShallowCopy(copies);
00286     deepCopyField(missing_instructions, copies);
00287 }
00288 
00289 } // end of namespace PLearn
00290 
00291 
00292 /*
00293   Local Variables:
00294   mode:c++
00295   c-basic-offset:4
00296   c-file-style:"stroustrup"
00297   c-file-offsets:((innamespace . 0)(inline-open . 0))
00298   indent-tabs-mode:nil
00299   fill-column:79
00300   End:
00301 */
00302 // 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