main.cc

00001 /* MLPACK 0.2
00002  *
00003  * Copyright (c) 2008, 2009 Alexander Gray,
00004  *                          Garry Boyer,
00005  *                          Ryan Riegel,
00006  *                          Nikolaos Vasiloglou,
00007  *                          Dongryeol Lee,
00008  *                          Chip Mappus, 
00009  *                          Nishant Mehta,
00010  *                          Hua Ouyang,
00011  *                          Parikshit Ram,
00012  *                          Long Tran,
00013  *                          Wee Chin Wong
00014  *
00015  * Copyright (c) 2008, 2009 Georgia Institute of Technology
00016  *
00017  * This program is free software; you can redistribute it and/or
00018  * modify it under the terms of the GNU General Public License as
00019  * published by the Free Software Foundation; either version 2 of the
00020  * License, or (at your option) any later version.
00021  *
00022  * This program is distributed in the hope that it will be useful, but
00023  * WITHOUT ANY WARRANTY; without even the implied warranty of
00024  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00025  * General Public License for more details.
00026  *
00027  * You should have received a copy of the GNU General Public License
00028  * along with this program; if not, write to the Free Software
00029  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00030  * 02110-1301, USA.
00031  */
00039 #include "fastlib/fastlib.h"
00040 #include "kernel_aux.h"
00041 #include "farfield_expansion.h"
00042 #include "mult_farfield_expansion.h"
00043 #include "local_expansion.h"
00044 #include "mult_local_expansion.h"
00045 #include "mult_series_expansion_aux.h"
00046 #include "../kde/dataset_scaler.h"
00047 
00048 int TestEpanKernelTranslateFarToLocalField(const Matrix &data, 
00049                                            const Vector &weights,
00050                                            int begin, int end) {
00051   
00052   printf("\n----- TestEpanKernelTranslateFarToLocalField -----\n");
00053 
00054   // bandwidth of 16 Epanechnikov kernel
00055   double bandwidth = 20;
00056 
00057   // declare auxiliary object and initialize
00058   EpanKernelAux ka;
00059   ka.Init(bandwidth, 10, data.n_rows());
00060 
00061   // declare center at the origin
00062   Vector center;
00063   center.Init(data.n_rows());
00064   center.SetZero();
00065 
00066   // to-be-evaluated point
00067   Vector evaluate_here;
00068   evaluate_here.Init(data.n_rows());
00069   evaluate_here.SetAll(1);
00070 
00071   // declare expansion object
00072   FarFieldExpansion<EpanKernelAux> se;
00073 
00074   // initialize expansion objects with respective center and the bandwidth
00075   se.Init(center, ka);
00076 
00077   // compute up to 2-nd order multivariate polynomial.
00078   se.AccumulateCoeffs(data, weights, begin, end, 2);
00079 
00080   // print out the objects
00081   se.PrintDebug();               // expansion at (0, 0)
00082 
00083   // evaluate the series expansion
00084   printf("Evaluated the expansion at (%g) is %g...\n",
00085          evaluate_here[0],
00086          se.EvaluateField(evaluate_here.ptr(), 2));
00087 
00088   LocalExpansion<EpanKernelAux> local_se;
00089   Vector local_center;
00090   local_center.Init(data.n_rows());
00091   local_center.SetAll(5);
00092   local_se.Init(local_center, ka);
00093   se.TranslateToLocal(local_se, 2);
00094 
00095   local_se.PrintDebug();
00096 
00097   printf("Evaluated the expansion at the local expansion: %g...\n",
00098          local_se.EvaluateField(evaluate_here.ptr()));
00099 
00100   // check with exhaustive method
00101   double exhaustive_sum = 0;
00102   for(index_t i = begin; i < end; i++) {
00103     int row_num = i;
00104     double dsqd = math::Sqr(evaluate_here[0] - data.get(0, row_num)) + 
00105       math::Sqr(evaluate_here[1] - data.get(1, row_num));
00106     
00107     exhaustive_sum += ka.kernel_.EvalUnnormOnSq(dsqd);
00108 
00109   }
00110   printf("Exhaustively evaluated sum: %g\n", exhaustive_sum);
00111 
00112   /*
00113   // now recompute using the old expansion formula...
00114   double first_moment0 = 0;
00115   double first_moment1 = 0;
00116   double second_moment0 = 0;
00117   double second_moment1 = 0;
00118 
00119   for(index_t i = begin; i < end; i++) {
00120     int row_num = i;
00121 
00122     double diff0 = (data.get(0, row_num) - center[0]) / 
00123       sqrt(ka.kernel_.bandwidth_sq());    
00124     double diff1 = (data.get(1, row_num) - center[1]) / 
00125       sqrt(ka.kernel_.bandwidth_sq());
00126     
00127 
00128     first_moment0 += diff0;
00129     first_moment1 += diff1;
00130     second_moment0 += diff0 * diff0;
00131     second_moment1 += diff1 * diff1;
00132   }
00133   double diff_coord0 = (evaluate_here[0] - center[0]) / 
00134     sqrt(ka.kernel_.bandwidth_sq());
00135   double diff_coord1 = (evaluate_here[1] - center[1]) / 
00136     sqrt(ka.kernel_.bandwidth_sq());
00137   
00138   printf("Old formula got: %g\n",
00139          end - (second_moment0 - 2 * first_moment0 * diff_coord0 + 
00140                 end * diff_coord0 * diff_coord0) - 
00141          (second_moment1 - 2 * first_moment1 * diff_coord1 + 
00142           end * diff_coord1 * diff_coord1));
00143   */
00144 
00145   return 1;
00146 }
00147 
00148 int TestEpanKernelEvaluateFarField(const Matrix &data, const Vector &weights,
00149                                    int begin, int end) {
00150   
00151   printf("\n----- TestEpanKernelEvaluateFarField -----\n");
00152 
00153   // bandwidth of 10 Epanechnikov kernel
00154   double bandwidth = 10;
00155 
00156   // declare auxiliary object and initialize
00157   EpanKernelAux ka;
00158   ka.Init(bandwidth, 10, data.n_rows());
00159 
00160   // declare center at the origin
00161   Vector center;
00162   center.Init(2);
00163   center.SetZero();
00164 
00165   // to-be-evaluated point
00166   Vector evaluate_here;
00167   evaluate_here.Init(2);
00168   evaluate_here[0] = evaluate_here[1] = 0.1;
00169 
00170   // declare expansion object
00171   FarFieldExpansion<EpanKernelAux> se;
00172 
00173   // initialize expansion objects with respective center and the bandwidth
00174   se.Init(center, ka);
00175 
00176   // compute up to 2-nd order multivariate polynomial.
00177   se.AccumulateCoeffs(data, weights, begin, end, 2);
00178 
00179   // print out the objects
00180   se.PrintDebug();               // expansion at (0, 0)
00181 
00182   // evaluate the series expansion
00183   printf("Evaluated the expansion at (%g %g) is %g...\n",
00184          evaluate_here[0], evaluate_here[1],
00185          se.EvaluateField(evaluate_here.ptr(), 2));
00186 
00187   // check with exhaustive method
00188   double exhaustive_sum = 0;
00189   for(index_t i = begin; i < end; i++) {
00190     int row_num = i;
00191     double dsqd = (evaluate_here[0] - data.get(0, row_num)) * 
00192       (evaluate_here[0] - data.get(0, row_num)) +
00193       (evaluate_here[1] - data.get(1, row_num)) * 
00194       (evaluate_here[1] - data.get(1, row_num));
00195     
00196     exhaustive_sum += ka.kernel_.EvalUnnormOnSq(dsqd);
00197 
00198   }
00199   printf("Exhaustively evaluated sum: %g\n", exhaustive_sum);
00200 
00201   // now recompute using the old expansion formula...
00202   double first_moment0 = 0;
00203   double first_moment1 = 0;
00204   double second_moment0 = 0;
00205   double second_moment1 = 0;
00206 
00207   for(index_t i = begin; i < end; i++) {
00208     int row_num = i;
00209 
00210     double diff0 = (data.get(0, row_num) - center[0]) / 
00211       sqrt(ka.kernel_.bandwidth_sq());
00212     double diff1 = (data.get(1, row_num) - center[1]) / 
00213       sqrt(ka.kernel_.bandwidth_sq());
00214 
00215     first_moment0 += diff0;
00216     first_moment1 += diff1;
00217     second_moment0 += diff0 * diff0;
00218     second_moment1 += diff1 * diff1;
00219   }
00220   double diff_coord0 = (evaluate_here[0] - center[0]) / 
00221     sqrt(ka.kernel_.bandwidth_sq());
00222   double diff_coord1 = (evaluate_here[1] - center[1]) / 
00223     sqrt(ka.kernel_.bandwidth_sq());
00224   
00225   printf("Old formula got: %g\n",
00226          end - (second_moment0 - 2 * first_moment0 * diff_coord0 + 
00227                 end * diff_coord0 * diff_coord0) - 
00228          (second_moment1 - 2 * first_moment1 * diff_coord1 + 
00229           end * diff_coord1 * diff_coord1));
00230 
00231   return 1;
00232 }
00233 
00234 int TestEpanKernelEvaluateLocalField(const Matrix &data, const Vector &weights,
00235                                      int begin, int end) {
00236   
00237   printf("\n----- TestEpanKernelEvaluateLocalField -----\n");
00238 
00239   // bandwidth of 10 Epanechnikov kernel
00240   double bandwidth = 10;
00241 
00242   // declare auxiliary object and initialize
00243   EpanKernelAux ka;
00244   ka.Init(bandwidth, 10, data.n_rows());
00245 
00246   // declare center at the origin
00247   Vector center;
00248   center.Init(2);
00249   center.SetZero();
00250 
00251   // to-be-evaluated point
00252   Vector evaluate_here;
00253   evaluate_here.Init(2);
00254   evaluate_here[0] = evaluate_here[1] = 0.1;
00255 
00256   // declare expansion object
00257   LocalExpansion<EpanKernelAux> se;
00258 
00259   // initialize expansion objects with respective center and the bandwidth
00260   se.Init(center, ka);
00261 
00262   // compute up to 2-nd order multivariate polynomial.
00263   se.AccumulateCoeffs(data, weights, begin, end, 2);
00264 
00265   // print out the objects
00266   se.PrintDebug();               // expansion at (0, 0)
00267 
00268   // evaluate the series expansion
00269   printf("Evaluated the expansion at (%g %g) is %g...\n",
00270          evaluate_here[0], evaluate_here[1],
00271          se.EvaluateField(evaluate_here.ptr()));
00272 
00273   // check with exhaustive method
00274   double exhaustive_sum = 0;
00275   for(index_t i = begin; i < end; i++) {
00276     int row_num = i;
00277     double dsqd = (evaluate_here[0] - data.get(0, row_num)) * 
00278       (evaluate_here[0] - data.get(0, row_num)) +
00279       (evaluate_here[1] - data.get(1, row_num)) * 
00280       (evaluate_here[1] - data.get(1, row_num));
00281     
00282     exhaustive_sum += ka.kernel_.EvalUnnormOnSq(dsqd);
00283 
00284   }
00285   printf("Exhaustively evaluated sum: %g\n", exhaustive_sum);
00286 
00287   // now recompute using the old expansion formula...
00288   double first_moment0 = 0;
00289   double first_moment1 = 0;
00290   double second_moment0 = 0;
00291   double second_moment1 = 0;
00292 
00293   for(index_t i = begin; i < end; i++) {
00294     int row_num = i;
00295 
00296     double diff0 = (data.get(0, row_num) - center[0]) / 
00297       sqrt(ka.kernel_.bandwidth_sq());
00298     double diff1 = (data.get(1, row_num) - center[1]) / 
00299       sqrt(ka.kernel_.bandwidth_sq());
00300 
00301     first_moment0 += diff0;
00302     first_moment1 += diff1;
00303     second_moment0 += diff0 * diff0;
00304     second_moment1 += diff1 * diff1;
00305   }
00306   double diff_coord0 = (evaluate_here[0] - center[0]) / 
00307     sqrt(ka.kernel_.bandwidth_sq());
00308   double diff_coord1 = (evaluate_here[1] - center[1]) / 
00309     sqrt(ka.kernel_.bandwidth_sq());
00310   
00311   printf("Old formula got: %g\n",
00312          end - (second_moment0 - 2 * first_moment0 * diff_coord0 + 
00313                 end * diff_coord0 * diff_coord0) - 
00314          (second_moment1 - 2 * first_moment1 * diff_coord1 + 
00315           end * diff_coord1 * diff_coord1));
00316 
00317   return 1;
00318 }
00319 
00320 int TestEvaluateFarField(const Matrix &data, const Vector &weights,
00321                          int begin, int end) {
00322   
00323   printf("\n----- TestEvaluateFarField -----\n");
00324 
00325   // bandwidth of sqrt(0.5) Gaussian kernel
00326   double bandwidth = sqrt(0.5);
00327 
00328   // declare auxiliary object and initialize
00329   GaussianKernelAux ka;
00330   ka.Init(bandwidth, 10, data.n_rows());
00331 
00332   // declare center at the origin
00333   Vector center;
00334   center.Init(2);
00335   center.SetZero();
00336 
00337   // to-be-evaluated point
00338   Vector evaluate_here;
00339   evaluate_here.Init(2);
00340   evaluate_here[0] = evaluate_here[1] = 7;
00341 
00342   // declare expansion objects at (0,0) and other centers
00343   FarFieldExpansion<GaussianKernelAux> se;
00344 
00345   // initialize expansion objects with respective centers and the bandwidth
00346   // squared of 0.5
00347   se.Init(center, ka);
00348 
00349   // compute up to 10-th order multivariate polynomial.
00350   se.AccumulateCoeffs(data, weights, begin, end, 10);
00351 
00352   // print out the objects
00353   se.PrintDebug();               // expansion at (0, 0)
00354 
00355   // evaluate the series expansion
00356   printf("Evaluated the expansion at (%g %g) is %g...\n",
00357          evaluate_here[0], evaluate_here[1],
00358          se.EvaluateField(evaluate_here.ptr(), 10));
00359 
00360   // check with exhaustive method
00361   double exhaustive_sum = 0;
00362   for(index_t i = begin; i < end; i++) {
00363     int row_num = i;
00364     double dsqd = (evaluate_here[0] - data.get(0, row_num)) * 
00365       (evaluate_here[0] - data.get(0, row_num)) +
00366       (evaluate_here[1] - data.get(1, row_num)) * 
00367       (evaluate_here[1] - data.get(1, row_num));
00368     
00369     exhaustive_sum += ka.kernel_.EvalUnnormOnSq(dsqd);
00370 
00371   }
00372   printf("Exhaustively evaluated sum: %g\n", exhaustive_sum);
00373   return 1;
00374 }
00375 
00376 int TestEvaluateLocalField(const Matrix &data, const Vector &weights,
00377                            int begin, int end) {
00378 
00379   printf("\n----- TestEvaluateLocalField -----\n");
00380 
00381   // declare auxiliary object and initialize
00382   double bandwidth = 1;
00383   GaussianKernelAux ka;
00384   ka.Init(bandwidth, 10, data.n_rows());
00385 
00386   // declare center at the origin
00387   Vector center;
00388   center.Init(2);
00389   center[0] = center[1] = 4;
00390 
00391   // to-be-evaluated point
00392   Vector evaluate_here;
00393   evaluate_here.Init(2);
00394   evaluate_here[0] = evaluate_here[1] = 3.5;
00395 
00396   // declare expansion objects at (0,0) and other centers
00397   LocalExpansion<GaussianKernelAux> se;
00398 
00399   // initialize expansion objects with respective centers and the bandwidth
00400   // squared of 1
00401   se.Init(center, ka);
00402 
00403   // compute up to 4-th order multivariate polynomial.
00404   se.AccumulateCoeffs(data, weights, begin, end, 6);
00405 
00406   // print out the objects
00407   se.PrintDebug();
00408 
00409   // evaluate the series expansion
00410   printf("Evaluated the expansion at (%g %g) is %g...\n",
00411          evaluate_here[0], evaluate_here[1],
00412          se.EvaluateField(evaluate_here.ptr()));
00413   
00414   // check with exhaustive method
00415   double exhaustive_sum = 0;
00416   for(index_t i = begin; i < end; i++) {
00417     int row_num = i;
00418 
00419     double dsqd = (evaluate_here[0] - data.get(0, row_num)) * 
00420       (evaluate_here[0] - data.get(0, row_num)) +
00421       (evaluate_here[1] - data.get(1, row_num)) * 
00422       (evaluate_here[1] - data.get(1, row_num));
00423     
00424     exhaustive_sum += ka.kernel_.EvalUnnormOnSq(dsqd);
00425 
00426   }
00427   printf("Exhaustively evaluated sum: %g\n", exhaustive_sum);
00428   return 1;
00429 }
00430 
00431 int TestInitAux(const Matrix& data) {
00432 
00433   printf("\n----- TestInitAux -----\n");
00434 
00435   SeriesExpansionAux sea;
00436   sea.Init(10, data.n_rows());
00437   sea.PrintDebug();
00438 
00439   return 1;
00440 }
00441 
00442 int TestTransFarToFar(const Matrix &data, const Vector &weights,
00443                       int begin, int end) {
00444 
00445   printf("\n----- TestTransFarToFar -----\n");
00446 
00447   // declare auxiliary object and initialize
00448   double bandwidth = sqrt(0.1);
00449   GaussianKernelAux ka;
00450   ka.Init(bandwidth, 10, data.n_rows());
00451   
00452   // declare center at the origin
00453   Vector center;
00454   center.Init(2);
00455   center.SetZero();
00456 
00457   // declare a new center at (2, -2)
00458   Vector new_center;
00459   new_center.Init(2);
00460   new_center[0] = 2;
00461   new_center[1] = -2;
00462 
00463   // declare expansion objects at (0,0) and other centers
00464   FarFieldExpansion<GaussianKernelAux> se;
00465   FarFieldExpansion<GaussianKernelAux> se_translated;
00466   FarFieldExpansion<GaussianKernelAux> se_cmp;
00467 
00468   // initialize expansion objects with respective centers and the bandwidth
00469   // squared of 0.1
00470   se.Init(center, ka);
00471   se_translated.Init(new_center, ka);
00472   se_cmp.Init(new_center, ka);
00473   
00474   // compute up to 4-th order multivariate polynomial and translate it.
00475   se.AccumulateCoeffs(data, weights, begin, end, 4);
00476   se_translated.TranslateFromFarField(se);
00477   
00478   // now compute the same thing at (2, -2) and compare
00479   se_cmp.AccumulateCoeffs(data, weights, begin, end, 4);
00480 
00481   // print out the objects
00482   se.PrintDebug();               // expansion at (0, 0)
00483   se_translated.PrintDebug();    // expansion at (2, -2) translated from
00484                                  // one above
00485   se_cmp.PrintDebug();           // directly computed expansion at (2, -2)
00486 
00487   // retrieve the coefficients of se_translated and se_cmp
00488   Vector se_translated_coeffs;
00489   Vector se_cmp_coeffs;
00490   se_translated_coeffs.Alias(se_translated.get_coeffs());
00491   se_cmp_coeffs.Alias(se_cmp.get_coeffs());
00492 
00493   // assert that se_translated and se_cmp have equal set of coefficients
00494   // within 0.1 % error taking account the numerical errors
00495   for(index_t i = 0; i < se_cmp_coeffs.length(); i++) {
00496     if(fabs(se_translated_coeffs[i] - se_cmp_coeffs[i]) > 
00497        0.001 * fabs(se_cmp_coeffs[i])) {
00498       return 0;
00499     }
00500   }
00501   
00502   return 1;
00503 }
00504 
00505 int TestTransLocalToLocal(const Matrix &data, const Vector &weights,
00506                           int begin, int end) {
00507   
00508   printf("\n----- TestTransLocalToLocal -----\n");
00509 
00510   // declare auxiliary object and initialize
00511   double bandwidth = sqrt(1);
00512   GaussianKernelAux ka;
00513   ka.Init(bandwidth, 10, data.n_rows());
00514   
00515   // declare center at the origin
00516   Vector center;
00517   center.Init(2);
00518   center[0] = center[1] = 4;
00519 
00520   // declare a new center at (1, -1)
00521   Vector new_center;
00522   new_center.Init(2);
00523   new_center[0] = new_center[1] = 3.5;
00524 
00525   // declare expansion objects at (0,0) and other centers
00526   LocalExpansion<GaussianKernelAux> se;
00527   LocalExpansion<GaussianKernelAux> se_translated;
00528 
00529   // initialize expansion objects with respective centers and the bandwidth
00530   // squared of 0.1
00531   se.Init(center, ka);
00532   se_translated.Init(new_center, ka);
00533   
00534   // compute up to 4-th order multivariate polynomial and translate it.
00535   se.AccumulateCoeffs(data, weights, begin, end, 4);
00536   se.TranslateToLocal(se_translated);
00537 
00538   // print out the objects
00539   se.PrintDebug();               // expansion at (4, 4)
00540   se_translated.PrintDebug();    // expansion at (3.5, 3.5) translated from
00541                                  // one above
00542 
00543   // evaluate the expansion
00544   Vector evaluate_here;
00545   evaluate_here.Init(2);
00546   evaluate_here[0] = evaluate_here[1] = 3.75;
00547   double original_sum = se.EvaluateField(evaluate_here.ptr());
00548   double translated_sum = 
00549     se_translated.EvaluateField(evaluate_here.ptr());
00550 
00551   printf("Evaluating both expansions at (%g %g)...\n", evaluate_here[0],
00552          evaluate_here[1]);
00553   printf("Sum evaluated at the original local expansion: %g\n", original_sum);
00554   printf("Sum evaluated at the translated local expansion: %g\n",
00555          translated_sum);
00556 
00557   if(fabs(original_sum - translated_sum) > 0.001 * fabs(original_sum)) {
00558     return 0;
00559   }
00560   return 1;
00561 }
00562 
00563 int TestMixFarField(const Matrix &data, const Vector &weights,
00564                     int begin, int end) {
00565   
00566   printf("\n----- TestMixFarField -----\n");
00567 
00568   // bandwidth of 5 Gaussian kernel
00569   double bandwidth = 5;
00570 
00571   // declare auxiliary object and initialize
00572   GaussianKernelAux ka;
00573   ka.Init(bandwidth, 20, data.n_rows());
00574 
00575   // declare center at the origin, (10, -10) and (-10, -10)
00576   Vector center;
00577   center.Init(2);
00578   center.SetZero();
00579   Vector center2;
00580   center2.Init(2);
00581   center2[0] = 10; center2[1] = -10;
00582   Vector center3;
00583   center3.Init(2);
00584   center3[0] = center3[1] = -10;
00585 
00586   // create fake data
00587   Matrix data_comb;
00588   data_comb.Init(data.n_rows(), data.n_cols() * 3);
00589   for(index_t c = 0; c < data.n_cols(); c++) {
00590     data_comb.set(0, c, data.get(0, c));
00591     data_comb.set(1, c, data.get(1, c));
00592     data_comb.set(0, c + data.n_cols(), data.get(0, c) + center2[0]);
00593     data_comb.set(1, c + data.n_cols(), data.get(1, c) + center2[1]);
00594     data_comb.set(0, c + 2 * data.n_cols(), data.get(0, c) + center3[0]);
00595     data_comb.set(1, c + 2 * data.n_cols(), data.get(1, c) + center3[1]);
00596   }
00597   Vector weights_comb;
00598   weights_comb.Init(data.n_cols() * 3);
00599   weights_comb.SetAll(1);
00600 
00601   data_comb.PrintDebug();
00602 
00603   // declare expansion objects at (0,0) and other centers
00604   FarFieldExpansion<GaussianKernelAux> se;
00605   FarFieldExpansion<GaussianKernelAux> se2;
00606   FarFieldExpansion<GaussianKernelAux> se3;
00607 
00608   // initialize expansion objects with respective centers and the bandwidth
00609   // squared of 0.5
00610   se.Init(center, ka);
00611   se2.Init(center2, ka);
00612   se3.Init(center3, ka);
00613 
00614   // compute up to 20-th order multivariate polynomial.
00615   se.AccumulateCoeffs(data_comb, weights_comb, begin, end, 20);
00616   se2.AccumulateCoeffs(data_comb, weights_comb, begin + data.n_cols(), 
00617                        end + data.n_cols(), 20);
00618   se3.AccumulateCoeffs(data_comb, weights_comb, begin + 2 * data.n_cols(), 
00619                        end + 2 * data.n_cols(), 20);
00620 
00621   printf("Convolution: %g\n", se.MixField(data_comb, begin, end, 
00622                                           begin + data.n_cols(), 
00623                                           end + data.n_cols(),
00624                                           se2, se3, 6, 6));
00625 
00626   // compare with naive
00627   double naive_result = 0;
00628   for(index_t i = 0; i < data.n_cols(); i++) {
00629     const double *i_col = data_comb.GetColumnPtr(i);
00630     for(index_t j = data.n_cols(); j < 2 * data.n_cols(); j++) {
00631       const double *j_col = data_comb.GetColumnPtr(j);
00632       for(index_t k = 2 * data.n_cols(); k < 3 * data.n_cols(); k++) {
00633         const double *k_col = data_comb.GetColumnPtr(k);
00634 
00635         // compute pairwise distances
00636         double dsqd_ij = 0;
00637         double dsqd_ik = 0;
00638         double dsqd_jk = 0;
00639         for(index_t d = 0; d < ka.sea_.get_dimension(); d++) {
00640           dsqd_ij += (i_col[d] - j_col[d]) * (i_col[d] - j_col[d]);
00641           dsqd_ik += (i_col[d] - k_col[d]) * (i_col[d] - k_col[d]);
00642           dsqd_jk += (j_col[d] - k_col[d]) * (j_col[d] - k_col[d]);
00643         }
00644         naive_result += ka.kernel_.EvalUnnormOnSq(dsqd_ij + dsqd_ik +
00645                                                   dsqd_jk);
00646       }
00647     }
00648   }
00649   printf("Naive algorithm: %g\n", naive_result);
00650   return 1;
00651 }
00652 
00653 int TestConvolveFarField(const Matrix &data, const Vector &weights,
00654                          int begin, int end) {
00655   
00656   printf("\n----- TestConvolveFarField -----\n");
00657 
00658   // bandwidth of 5 Gaussian kernel
00659   double bandwidth = 5;
00660 
00661   // declare auxiliary object and initialize
00662   GaussianKernelAux ka;
00663   ka.Init(bandwidth, 20, data.n_rows());
00664 
00665   // declare center at the origin, (10, -10) and (-10, -10)
00666   Vector center;
00667   center.Init(2);
00668   center.SetZero();
00669   Vector center2;
00670   center2.Init(2);
00671   center2[0] = 10; center2[1] = -10;
00672   Vector center3;
00673   center3.Init(2);
00674   center3[0] = center3[1] = -10;
00675 
00676   // create fake data
00677   Matrix data2, data3;
00678   data2.Copy(data);
00679   data3.Copy(data);
00680   for(index_t c = 0; c < data.n_cols(); c++) {
00681     data2.set(0, c, data2.get(0, c) + center2[0]); 
00682     data2.set(1, c, data2.get(1, c) + center2[1]);
00683     data3.set(0, c, data3.get(0, c) + center3[0]);
00684     data3.set(1, c, data3.get(1, c) + center3[1]);
00685   }
00686 
00687   data.PrintDebug();
00688   data2.PrintDebug();
00689   data3.PrintDebug();
00690 
00691   // declare expansion objects at (0,0) and other centers
00692   FarFieldExpansion<GaussianKernelAux> se;
00693   FarFieldExpansion<GaussianKernelAux> se2;
00694   FarFieldExpansion<GaussianKernelAux> se3;
00695 
00696   // initialize expansion objects with respective centers and the bandwidth
00697   // squared of 0.5
00698   se.Init(center, ka);
00699   se2.Init(center2, ka);
00700   se3.Init(center3, ka);
00701 
00702   // compute up to 20-th order multivariate polynomial.
00703   se.AccumulateCoeffs(data, weights, begin, end, 20);
00704   se2.AccumulateCoeffs(data2, weights, begin, end, 20);
00705   se3.AccumulateCoeffs(data3, weights, begin, end, 20);
00706 
00707   printf("Convolution: %g\n", se.ConvolveField(se2, se3, 6, 6, 6));
00708 
00709   // compare with naive
00710   double naive_result = 0;
00711   for(index_t i = 0; i < data.n_cols(); i++) {
00712     const double *i_col = data.GetColumnPtr(i);
00713     for(index_t j = 0; j < data2.n_cols(); j++) {
00714       const double *j_col = data2.GetColumnPtr(j);
00715       for(index_t k = 0; k < data3.n_cols(); k++) {
00716         const double *k_col = data3.GetColumnPtr(k);
00717 
00718         // compute pairwise distances
00719         double dsqd_ij = 0;
00720         double dsqd_ik = 0;
00721         double dsqd_jk = 0;
00722         for(index_t d = 0; d < ka.sea_.get_dimension(); d++) {
00723           dsqd_ij += (i_col[d] - j_col[d]) * (i_col[d] - j_col[d]);
00724           dsqd_ik += (i_col[d] - k_col[d]) * (i_col[d] - k_col[d]);
00725           dsqd_jk += (j_col[d] - k_col[d]) * (j_col[d] - k_col[d]);
00726         }
00727         naive_result += ka.kernel_.EvalUnnormOnSq(dsqd_ij + dsqd_ik +
00728                                                   dsqd_jk);
00729       }
00730     }
00731   }
00732   printf("Naive algorithm: %g\n", naive_result);
00733   return 1;
00734 }
00735 
00736 int TestMultInitAux(const Matrix& data) {
00737 
00738   printf("\n----- TestMultInitAux -----\n");
00739 
00740   MultSeriesExpansionAux msea;
00741   msea.Init(2, data.n_rows());
00742   msea.PrintDebug();
00743 
00744   return 1;
00745 }
00746 
00747 int TestMultEvaluateFarField(const Matrix &data, const Vector &weights,
00748                              int begin, int end) {
00749   
00750   printf("\n----- TestMultEvaluateFarField -----\n");
00751 
00752   // bandwidth of sqrt(0.5) Gaussian kernel
00753   double bandwidth = sqrt(0.5);
00754 
00755   // declare auxiliary object and initialize
00756   GaussianKernelMultAux ka;
00757   ka.Init(bandwidth, 2, data.n_rows());
00758 
00759   // declare center at the origin
00760   Vector center;
00761   center.Init(3);
00762   center.SetZero();
00763 
00764   // to-be-evaluated point
00765   Vector evaluate_here;
00766   evaluate_here.Init(2);
00767   evaluate_here[0] = evaluate_here[1] = 3;
00768 
00769   // declare expansion objects at (0,0) and other centers
00770   MultFarFieldExpansion<GaussianKernelMultAux> se;
00771 
00772   // initialize expansion objects with respective centers and the bandwidth
00773   // squared of 0.5
00774   se.Init(center, ka);
00775 
00776   // compute up to 4-th order multivariate polynomial.
00777   se.AccumulateCoeffs(data, weights, begin, end, 1);
00778 
00779   // print out the objects
00780   se.PrintDebug();               // expansion at (0, 0)
00781 
00782   return 1;
00783 }
00784 
00785 int main(int argc, char *argv[]) {
00786 
00787   fx_init(argc, argv, NULL);
00788 
00789   const char *datafile_name = fx_param_str(fx_root, "data", NULL);
00790   Dataset dataset;
00791   Matrix data;
00792   Vector weights;
00793   int begin, end;
00794 
00795   // read the dataset and get the matrix
00796   if (!PASSED(dataset.InitFromFile(datafile_name))) {
00797     fprintf(stderr, "main: Couldn't open file '%s'.\n", datafile_name);
00798     return 1;
00799   }
00800   data.Alias(dataset.matrix());
00801   weights.Init(data.n_cols());
00802   weights.SetAll(1);
00803   begin = 0; end = data.n_cols();
00804 
00805   // unit tests begin here!  
00806   DEBUG_ASSERT(TestInitAux(data) == 1);
00807   DEBUG_ASSERT(TestEvaluateFarField(data, weights, begin, end) == 1);
00808   DEBUG_ASSERT(TestEvaluateLocalField(data, weights, begin, end) == 1);
00809   DEBUG_ASSERT(TestTransFarToFar(data, weights, begin, end) == 1);
00810   DEBUG_ASSERT(TestTransLocalToLocal(data, weights, begin, end) == 1);
00811 
00812   DEBUG_ASSERT(TestEpanKernelEvaluateFarField(data, weights, begin, end) == 1);
00813 
00814   DEBUG_ASSERT(TestConvolveFarField(data, weights, begin, end) == 1);
00815   DEBUG_ASSERT(TestMixFarField(data, weights, begin, end) == 1);
00816 
00817   DEBUG_ASSERT(TestMultInitAux(data) == 1);
00818   DEBUG_ASSERT(TestMultEvaluateFarField(data, weights, begin, end) == 1);
00819 
00820   fx_done(fx_root);
00821 }
Generated on Mon Jan 24 12:04:37 2011 for FASTlib by  doxygen 1.6.3