PLearn 0.1
CartesianProductOracle.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // CartesianProductOracle.cc
00004 //
00005 // Copyright (C) 2003-2004 ApSTAT Technologies Inc.
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: CartesianProductOracle.cc 8897 2008-04-25 18:18:23Z nouiz $
00037  ******************************************************* */
00038 
00040 #include "CartesianProductOracle.h"
00041 
00042 namespace PLearn {
00043 using namespace std;
00044 
00045 CartesianProductOracle::CartesianProductOracle()
00046     :OptionsOracle(), last_combination(false)
00047 /* ### Initialise all fields to their default value */
00048 {
00049 }
00050 
00051 PLEARN_IMPLEMENT_OBJECT(
00052     CartesianProductOracle,
00053     "This OptionsOracle generates all combinations of values for a set of options",
00054     "This 'oracle' traverses a fixed list of option values, obtained from a set"
00055     "of values associated with each option of interest. That list is the cartesian"
00056     "product of those sets, i.e. it is the list of all combinations of values."
00057     "The user specifies the names of each option, and for each of them, a list"
00058     "of the values that should be tried."
00059     );
00060 
00061 void CartesianProductOracle::declareOptions(OptionList& ol)
00062 {
00063     declareOption(ol, "option_names", &CartesianProductOracle::option_names, OptionBase::buildoption,
00064                   "name of each of the options to optimize");
00065 
00066     declareOption(ol, "option_values", &CartesianProductOracle::option_values, OptionBase::buildoption,
00067                   "A list of lists of options: the top list must have as many elements as there are"
00068                   "options in the option_names field. Each sub-list contains the values to be tried"
00069                   "for the corresponding option."
00070         );
00071     declareOption(ol, "option_values_indices",
00072                   &CartesianProductOracle::option_values_indices,
00073                   OptionBase::learntoption,
00074                   "The indices of each option value.");
00075 
00076     // Now call the parent class' declareOptions
00077     inherited::declareOptions(ol);
00078 }
00079 
00080 TVec<string>  CartesianProductOracle::getOptionNames() const
00081 {
00082     return option_names;
00083 }
00084 
00085 TVec<string> CartesianProductOracle::generateNextTrial(const TVec<string>& older_trial,
00086                                                        real obtained_objective)
00087 {
00088     if (last_combination)
00089         return TVec<string>();
00090     else
00091     {
00092         int n=option_names.length();
00093         TVec<string> values(n);
00094         // copy current combination
00095         for (int i=0;i<n;i++)
00096             values[i]=option_values[i][option_values_indices[i]];
00097         // increment indices to next combination, in lexicographical order
00098         last_combination=true;
00099         for (int i=0;i<n;i++)
00100         {
00101             option_values_indices[i]++;
00102             if (option_values_indices[i]<option_values[i].length()) { last_combination=false; break; }
00103             else option_values_indices[i]=0;
00104         }
00105         return values;
00106     }
00107 }
00108 
00109 void CartesianProductOracle::forget()
00110 {
00111     option_values_indices.clear();
00112     last_combination=false;
00113 }
00114 
00115 void CartesianProductOracle::build_()
00116 {
00117     // Ensure consistency between option_names and option_values
00118     if (option_names.size() != option_values.size())
00119         PLERROR("CartesianProductOracle::build_: the 'option_names' and 'option_values'\n"
00120                 "fields don't have the same length; len(option_names)=%d / len(option_values)=%d",
00121                 option_names.size(), option_values.size());
00122     if (option_names.size() == 0 || option_values.size() == 0)
00123         PLWARNING("CartesianProductOracle::build_: either 'option_names' or 'option_values'\n"
00124                   "has size zero; is this what you want?");
00125 
00126     // Try to detect zero-length subarrays of options
00127     for (int i=0, n=option_values.size() ; i<n ; ++i)
00128         if (option_values[i].size() == 0)
00129             PLWARNING("CartesianProductOracle::build_: zero option values were specified\n"
00130                       "for option '%s'", option_names[i].c_str());
00131 
00132     option_values_indices.resize(option_names.length());
00133     forget();
00134 }
00135 
00136 // ### Nothing to add here, simply calls build_
00137 void CartesianProductOracle::build()
00138 {
00139     inherited::build();
00140     build_();
00141 }
00142 
00143 
00144 void CartesianProductOracle::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00145 {
00146     inherited::makeDeepCopyFromShallowCopy(copies);
00147     deepCopyField(option_values_indices, copies);
00148     deepCopyField(option_values, copies);
00149     deepCopyField(option_names, copies);
00150 }
00151 
00152 } // end of namespace PLearn
00153 
00154 
00155 /*
00156   Local Variables:
00157   mode:c++
00158   c-basic-offset:4
00159   c-file-style:"stroustrup"
00160   c-file-offsets:((innamespace . 0)(inline-open . 0))
00161   indent-tabs-mode:nil
00162   fill-column:79
00163   End:
00164 */
00165 // 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