PLearn 0.1
|
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 :