PLearn 0.1
SumEntropyOfCategoricals.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // SumEntropyOfCategoricals.cc
00004 //
00005 // Copyright (C) 2009 Pascal Vincent
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: Pascal Vincent
00036 
00040 #include "SumEntropyOfCategoricals.h"
00041 
00042 namespace PLearn {
00043 using namespace std;
00044 
00047 PLEARN_IMPLEMENT_OBJECT(
00048     SumEntropyOfCategoricals,
00049     "Computes the sum of the entropies of independent categorical variables (multinomials with number-of-trials n=1) whose probability parameters are given as input.",
00050     "i.e. if input is a matrix P, computes sum_ij - [P_ij log(P_ij)].\n"
00051     "Note that this formula does not depend on whether the parameters in P are those of a single categorical variable \n"
00052     "or represent the parameters of several independent categorical variables."
00053     );
00054 
00055 SumEntropyOfCategoricals::SumEntropyOfCategoricals()
00056     : inherited(0, 1, 1)
00057 {
00058 }
00059 
00060 // constructor from input variable.
00061 SumEntropyOfCategoricals::SumEntropyOfCategoricals(Variable* input)
00062     : inherited(input, 1, 1)
00063 {
00064     build_();
00065 }
00066 
00067 // constructor from input variable and parameters
00068 // SumEntropyOfCategoricals::SumEntropyOfCategoricals(Variable* input, param_type the_parameter,...)
00069 // ### replace with actual parameters
00070 //  : inherited(input, this_variable_length, this_variable_width),
00071 //    parameter(the_parameter),
00072 //    ...
00073 //{
00074 //    // ### You may (or not) want to call build_() to finish building the
00075 //    // ### object
00076 //}
00077 
00078 void SumEntropyOfCategoricals::recomputeSize(int& l, int& w) const
00079 {
00080     l = w = 1;
00081 }
00082 
00083 // ### computes value from input's value
00084 void SumEntropyOfCategoricals::fprop()
00085 {
00086     double res = 0;
00087     Mat P = input->matValue;
00088     int l = P.length();
00089     int w = P.width();
00090 
00091     for(int i=0; i<l; i++)
00092     {
00093         const real* P_i = P[i];
00094         for(int j=0; j<w; j++)
00095         {
00096             real P_ij = P_i[j];
00097             if( P_ij>1e-25 )
00098                 res += P_ij*pl_log(P_ij);
00099         }
00100     }
00101     valuedata[0] = -(real)res;
00102 }
00103 
00104 // ### computes input's gradient from gradient
00105 void SumEntropyOfCategoricals::bprop()
00106 {
00107     /*
00108       [-p log(p)]' = -[log(p) + 1]
00109     */
00110     real gr = gradientdata[0];
00111     Mat P = input->matValue;
00112     Mat Pgr = input->matGradient;
00113 
00114     int l = P.length();
00115     int w = P.width();
00116 
00117     for(int i=0; i<l; i++)
00118     {
00119         const real* P_i = P[i];
00120         real* Pgr_i = Pgr[i];
00121         for(int j=0; j<w; j++)
00122         {
00123             real P_ij = P_i[j];
00124             real logPij = P_ij>1e-25 ?pl_log(P_ij): -57.5;
00125             Pgr_i[j] -= gr*(logPij + 1);
00126         }
00127     }
00128 }
00129 
00130 // ### You can implement these methods:
00131 // void SumEntropyOfCategoricals::bbprop() {}
00132 // void SumEntropyOfCategoricals::symbolicBprop() {}
00133 // void SumEntropyOfCategoricals::rfprop() {}
00134 
00135 
00136 // ### Nothing to add here, simply calls build_
00137 void SumEntropyOfCategoricals::build()
00138 {
00139     inherited::build();
00140     build_();
00141 }
00142 
00143 void SumEntropyOfCategoricals::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00144 {
00145     inherited::makeDeepCopyFromShallowCopy(copies);
00146 }
00147 
00148 void SumEntropyOfCategoricals::declareOptions(OptionList& ol)
00149 {
00150     // ### Declare all of this object's options here.
00151     // ### For the "flags" of each option, you should typically specify
00152     // ### one of OptionBase::buildoption, OptionBase::learntoption or
00153     // ### OptionBase::tuningoption. If you don't provide one of these three,
00154     // ### this option will be ignored when loading values from a script.
00155     // ### You can also combine flags, for example with OptionBase::nosave:
00156     // ### (OptionBase::buildoption | OptionBase::nosave)
00157 
00158     // ### ex:
00159     // declareOption(ol, "myoption", &SumEntropyOfCategoricals::myoption,
00160     //               OptionBase::buildoption,
00161     //               "Help text describing this option");
00162     // ...
00163 
00164     // Now call the parent class' declareOptions
00165     inherited::declareOptions(ol);
00166 }
00167 
00168 void SumEntropyOfCategoricals::build_()
00169 {
00170     // ### This method should do the real building of the object,
00171     // ### according to set 'options', in *any* situation.
00172     // ### Typical situations include:
00173     // ###  - Initial building of an object from a few user-specified options
00174     // ###  - Building of a "reloaded" object: i.e. from the complete set of
00175     // ###    all serialised options.
00176     // ###  - Updating or "re-building" of an object after a few "tuning"
00177     // ###    options have been modified.
00178     // ### You should assume that the parent class' build_() has already been
00179     // ### called.
00180 }
00181 
00182 
00183 } // end of namespace PLearn
00184 
00185 
00186 /*
00187   Local Variables:
00188   mode:c++
00189   c-basic-offset:4
00190   c-file-style:"stroustrup"
00191   c-file-offsets:((innamespace . 0)(inline-open . 0))
00192   indent-tabs-mode:nil
00193   fill-column:79
00194   End:
00195 */
00196 // 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