PLearn 0.1
BetaKernel.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // BetaKernel.cc
00004 //
00005 // Copyright (C) 2008 Dumitru Erhan
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: Dumitru Erhan
00036 
00040 #include "BetaKernel.h"
00041 #include <plearn/math/distr_maths.h>
00042 
00043 namespace PLearn {
00044 using namespace std;
00045 
00046 PLEARN_IMPLEMENT_OBJECT(
00047     BetaKernel,
00048     "Several implementatins of the Beta kernel, for distributions that have support in the [0;1] range",
00049     "Useful for performing Parzen Windows-style density estimation. Need to specify the type of the kernel\n"
00050      "- simple: the basic Beta kernel \n"
00051      "- alternative: the alternative, faster converging version \n"
00052      "output_type should be set to either log_value or normal"  );
00053 
00055 // BetaKernel //
00057 BetaKernel::BetaKernel()
00058     : width(1.),
00059      kernel_type("simple"),
00060      output_type("normal")
00061 {
00062 }
00063 
00065 // declareOptions //
00067 void BetaKernel::declareOptions(OptionList& ol)
00068 {
00069 
00070     declareOption(ol, "width", &BetaKernel::width,
00071                    OptionBase::buildoption,
00072                   "The (positive, real-valued) smoothing parameter of the kernel (note that this does not quite correspond to the variance). If you use the Beta Kernel to do density estimation, this should go towards zero as the number of samples goes to infinity");
00073  
00074     declareOption(ol, "kernel_type", &BetaKernel::kernel_type,
00075                    OptionBase::buildoption,
00076                   "A string containing the type of Beta kernel. The \"simple\" kernel has a particularly simple mathematical form and is easily shown to integrate to 1 (thus is a density). The \"alternative\" kernel is slightly more complicated, but is better suited for those distributions that have a lot of mass near the boundaries (0 or 1). It will converge faster, but asymptotically both kernels are boundary bias free. Also, the \"alternative\" kernel is not yet shown by us to integrate to 1, thus we don't know for sure whether it's a valid density. Default is simple");
00077     
00078     declareOption(ol, "output_type", &BetaKernel::output_type,
00079                   OptionBase::buildoption,
00080                   "A string specifying whether we want log densities as outputs (\"log_value\" ) or just densities (\"normal\"; default)");
00081 
00082     // Now call the parent class' declareOptions
00083     inherited::declareOptions(ol);
00084 }
00085 
00087 // build //
00089 void BetaKernel::build()
00090 {
00091     // ### Nothing to add here, simply calls build_
00092     inherited::build();
00093     build_();
00094 }
00095 
00097 // build_ //
00099 void BetaKernel::build_()
00100 {
00101 }
00102 
00104 // evaluate //
00106 real BetaKernel::evaluate(const Vec& x1, const Vec& x2) const {
00107 #ifdef BOUNDCHECK
00108     if(x1.length()!=x2.length())
00109         PLERROR("In BetaKernel::evaluate x1 and x2 must have the same length");
00110 #endif
00111     int l = x1.length();
00112     real* px1 = x1.data();
00113     real* px2 = x2.data();
00114     real kvalue = 0.;
00115 
00116     //kernel_type = lowerstring(kernel_type);
00117 
00118     // check http://www.sta.nus.edu.sg/documents/publication_chen2.pdf for an
00119     // explanation of the estimators ("Beta kernel estimators for
00120     // density functions" is the paper title)
00121     if (kernel_type=="simple")
00122         for(int i=0; i<l; i++)
00123         {
00124             real a = px1[i] / width + 1.0;
00125             real b = (1.0 - px1[i]) / width + 1.0;
00126             real val = log_beta_density(px2[i],a,b);
00127             kvalue += val;
00128         }
00129     else if (kernel_type=="alternative")
00130         for(int i=0; i<l; i++)
00131         {
00132             real x = px1[i];
00133             real a, b;
00134 
00135             PLASSERT_MSG(x<0 || x >1 || px2[i] < 0 || px2[i] > 1, "In BetaKernel::evaluate x1 and x2 must contain values in the (closed) interval [0;1]");
00136 
00137             if ((x >= 2*width) && (x <= 1 - 2*width)) {
00138                 a = x / width;
00139                 b = (1 - x) / width;
00140             }
00141             else if ((x >= 0) & (x <= 2*width)) {
00142                 a = 2*pow(width,real(2)) + 2.5 - sqrt(4*pow(width,real(4)) + 6*pow(width,real(2)) + 2.25 - x*x - x / width);
00143                 b = (1 - x) / width;
00144             }
00145             else {
00146                 a = x / width;
00147                 real y = 1-x;
00148                 b = 2*pow(width,real(2)) + 2.5 - sqrt(4*pow(width,real(4))+ 6*pow(width,real(2)) + 2.25 - y*y - y / width);
00149             }
00150 
00151             real val = log_beta_density(px2[i],a,b);
00152             kvalue += val;
00153         }
00154     else
00155         PLERROR("In BetaKernel::evaluate kernel_type must be either \"simple\" or \"alternative\"");
00156 
00157     real retval = 0.0;
00158 
00159     if (output_type=="log_value")
00160         retval = kvalue;
00161     else if (output_type=="normal")
00162         retval = exp(kvalue);
00163     else
00164         PLERROR("In BetaKernel::evaluate output_type must be either \"log_value\" or \"normal\"");
00165 
00166     return retval;
00167 }
00168 
00169 /* ### This method will very often be overridden.
00171 // evaluate_i_j //
00173 real BetaKernel::evaluate_i_j(int i, int j) const {
00174 // ### Evaluate the kernel on a pair of training points.
00175 }
00176 */
00177 
00179 // makeDeepCopyFromShallowCopy //
00181 void BetaKernel::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00182 {
00183     inherited::makeDeepCopyFromShallowCopy(copies);
00184 }
00185 
00186 /* ### This method will be overridden if computations need to be done,
00187    ### or to forward the call to another object.
00188    ### In this case, be careful that it may be called BEFORE the build_()
00189    ### method has been called, if the 'specify_dataset' option is used.
00191 // setDataForKernelMatrix //
00193 void BetaKernel::setDataForKernelMatrix(VMat the_data) {
00194 }
00195 */
00196 
00197 } // end of namespace PLearn
00198 
00199 
00200 /*
00201   Local Variables:
00202   mode:c++
00203   c-basic-offset:4
00204   c-file-style:"stroustrup"
00205   c-file-offsets:((innamespace . 0)(inline-open . 0))
00206   indent-tabs-mode:nil
00207   fill-column:79
00208   End:
00209 */
00210 // 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