PLearn 0.1
PairwiseDiffsCommand.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // PairwiseDiffsCommand.cc
00004 //
00005 // Copyright (C) 2005 Nicolas Chapados 
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: PairwiseDiffsCommand.cc 8184 2007-10-15 20:09:46Z nouiz $ 
00037  ******************************************************* */
00038 
00039 // Authors: Nicolas Chapados
00040 
00043 // From PLearn
00044 #include "PairwiseDiffsCommand.h"
00045 #include <plearn/base/stringutils.h>
00046 #include <plearn/math/StatsCollector.h>
00047 #include <plearn/vmat/VMat.h>
00048 #include <plearn/db/getDataSet.h>
00049 
00050 // From C++ stdlib
00051 #include <deque>
00052 #include <iomanip>
00053 
00054 // From Boost
00055 #include <boost/format.hpp>
00056 
00057 namespace PLearn {
00058 using namespace std;
00059 using boost::format;
00060 
00062 PLearnCommandRegistry PairwiseDiffsCommand::reg_(new PairwiseDiffsCommand);
00063 
00064 PairwiseDiffsCommand::PairwiseDiffsCommand():
00065     PLearnCommand(
00066         "pairdiff",
00067         "Compute a set of statistics on the pairwise differences between cost matrices",
00068         " usage: pairdiff [--stats=E,PZ2t,...] costname costfile1.pmat costfile2.pmat ...\n"
00069         "\n"
00070         "This command computes a set of statistics (user-specified) on the\n"
00071         "pairwise differences between a given column of a list of matrices.  The\n"
00072         "typical usage is to give a list of test cost matrices (e.g. such as the\n"
00073         "'test_costs.pmat' files generated by PTester), and specify the cost of\n"
00074         "interest (column name) in the matrix.  For all of the matrices taken\n"
00075         "pairwise, the command will accumulate the DIFFERENCE of the specified\n"
00076         "columns in a stats collector, and then will output a set of\n"
00077         "user-specified statistics.  The default statistics are 'E' and 'PZ2t'\n"
00078         "(see the supported statistics in StatsCollector), meaning that the mean\n"
00079         "difference is computed, and the p-value that this difference is zero."
00080         )
00081 { }
00082 
00083 // Return a statscollector with the data accumulated from two matrices
00084 static PP<StatsCollector>
00085 accumInStatsCol(string costname, string file1, string file2)
00086 {
00087     VMat data1 = getDataSet(file1);
00088     VMat data2 = getDataSet(file2);
00089     int index1 = data1->getFieldIndex(costname);
00090     int index2 = data2->getFieldIndex(costname);
00091     if (index1 < 0)
00092         PLERROR("PairwiseDiffsCommand: fieldname '%s' does not exist in file '%s'",
00093                 costname.c_str(), file1.c_str());
00094     if (index2 < 0)
00095         PLERROR("PairwiseDiffsCommand: fieldname '%s' does not exist in file '%s'",
00096                 costname.c_str(), file2.c_str());
00097 
00098     int len = min(data1.length(), data2.length());
00099     if (len != data1.length() || len != data2.length())
00100         PLWARNING("PairwiseDiffsCommand: files '%s' and '%s' do not contain the same "
00101                   "number of rows; only comparing the first %d rows",
00102                   file1.c_str(), file2.c_str(), len);
00103 
00104     PP<StatsCollector> sc = new StatsCollector;
00105     for (int i=0; i<len; ++i) {
00106         real value1 = data1(i,index1);
00107         real value2 = data2(i,index2);
00108         sc->update(value1-value2);
00109     }
00110     return sc;
00111 }
00112   
00114 void PairwiseDiffsCommand::run(const vector<string>& origargs)
00115 {
00116     if (origargs.size() < 3)
00117         return;
00118 
00119     // Default arguments
00120     vector<string> stats;
00121     stats.push_back("E");
00122     stats.push_back("PZ2t");
00123 
00124     // Parse arguments
00125     deque<string> args(origargs.begin(), origargs.end());
00126     while (args[0].substr(0,2) == "--") {
00127         if (args[0].substr(0,8) == "--stats=") {
00128             string commastats = args[0].substr(8);
00129             stats = split(commastats,',');
00130         }
00131         args.pop_front();
00132     }
00133 
00134     string costname = args.front();
00135     args.pop_front();
00136 
00137     // Find maximum-length filename
00138     int maxlen = 0;
00139     for (int i=0, n=int(args.size()) ; i<n ; ++i)
00140         maxlen = max(maxlen, int(args[i].size()));
00141 
00142     // Print out heading row
00143     const int width = 15;
00144     cout.setf(ios_base::left);
00145     cout << setw(maxlen) << "Filename1" << ' '
00146          << setw(maxlen) << "Filename2" << ' ';
00147     cout.setf(ios_base::right);
00148     for (int i=0, n=int(stats.size()) ; i<n ; ++i)
00149         cout << setw(width) << stats[i] << ' ';
00150     cout << endl;
00151     cout.setf(ios_base::left);
00152   
00153     // What we have in args is a list of filenames.  Go over them.
00154     for (int i=0, n=int(args.size()) ; i < n-1 ; ++i) {
00155         for (int j=i+1 ; j < n ; ++j) {
00156             PP<StatsCollector> sc = accumInStatsCol(costname, args[i], args[j]);
00157 
00158             // Print out result
00159             cout << setw(maxlen) << args[i] << ' '
00160                  << setw(maxlen) << args[j] << ' ';
00161             for (int k=0, m=int(stats.size()) ; k<m ; ++k) {
00162                 real stat = sc->getStat(stats[k]);
00163                 cout << format("%+"+tostring(width)+".7f ") % stat;
00164             }
00165             cout << endl;
00166         }
00167     }
00168 }
00169 
00170 } // end of namespace PLearn
00171 
00172 
00173 /*
00174   Local Variables:
00175   mode:c++
00176   c-basic-offset:4
00177   c-file-style:"stroustrup"
00178   c-file-offsets:((innamespace . 0)(inline-open . 0))
00179   indent-tabs-mode:nil
00180   fill-column:79
00181   End:
00182 */
00183 // 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