series_expansion_aux.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  */
00032 #include <climits>
00033 //#include <values.h>
00034 
00035 #include "series_expansion_aux.h"
00036 
00037 const Vector& SeriesExpansionAux::get_inv_multiindex_factorials() const {
00038   return inv_multiindex_factorials_;
00039 }
00040 
00041 int SeriesExpansionAux::get_max_total_num_coeffs() const {
00042   return list_total_num_coeffs_[max_order_];
00043 }
00044 
00045 const ArrayList < int > *SeriesExpansionAux::get_lower_mapping_index() const {
00046   return lower_mapping_index_.begin();
00047 }
00048 
00049 int SeriesExpansionAux::get_max_order() const {
00050   return max_order_;
00051 }
00052 
00053 const ArrayList < int > &SeriesExpansionAux::get_multiindex(int pos) const {
00054   return multiindex_mapping_[pos];
00055 }
00056 
00057 const ArrayList < int > *SeriesExpansionAux::get_multiindex_mapping() const {
00058   return multiindex_mapping_.begin();
00059 }
00060 
00061 const Vector& SeriesExpansionAux::get_neg_inv_multiindex_factorials() const {
00062   return neg_inv_multiindex_factorials_;
00063 }
00064 
00065 double SeriesExpansionAux::get_n_choose_k(int n, int k) const {
00066   return n_choose_k_.get(n, (int) math::ClampNonNegative(k));
00067 }
00068 
00069 double SeriesExpansionAux::get_n_multichoose_k_by_pos(int n, int k) const {
00070   return multiindex_combination_.get(n, k);
00071 }
00072 
00073 int SeriesExpansionAux::get_total_num_coeffs(int order) const {
00074 
00075   return list_total_num_coeffs_[order];
00076 }
00077 
00078 const ArrayList < int > *SeriesExpansionAux::get_upper_mapping_index() const {
00079   return upper_mapping_index_.begin();
00080 }
00081 
00082 int SeriesExpansionAux::ComputeMultiindexPosition
00083 (const ArrayList<int> &multiindex) const {
00084 
00085   int dim = multiindex.size();
00086   int mapping_sum = 0;
00087   int index = 0;
00088 
00089   for(index_t j = 0; j < dim; j++) {
00090 
00091     // If any of the index is negative, then it does not exist!
00092     if(multiindex[j] < 0) {
00093       index = -1;
00094       break;
00095     }
00096     
00097     mapping_sum += multiindex[j];
00098   }
00099   if(index >= 0) {
00100     for(index_t j = 0; j < dim; j++) {
00101       index += (int) get_n_choose_k(mapping_sum + dim - j - 1, dim - j);
00102       mapping_sum -= multiindex[j];
00103     }
00104   }
00105   
00106   return index;
00107 }
00108 
00109 double SeriesExpansionAux::FarFieldEvaluationCost(int order) const {
00110   return pow(dim_, order + 1);
00111 }
00112 
00113 double SeriesExpansionAux::FarFieldToLocalTranslationCost(int order) const {
00114   return pow(dim_, 2 * order + 1);
00115 }
00116 
00117 double SeriesExpansionAux::DirectLocalAccumulationCost(int order) const {
00118   return pow(dim_, order + 1);
00119 }
00120 
00121 void SeriesExpansionAux::Init(int max_order, int dim) {
00122 
00123   int p, k, t, tail, i, j;
00124   ArrayList<int> heads;
00125   ArrayList<int> cinds;
00126 
00127   // initialize max order and dimension
00128   dim_ = dim;
00129   max_order_ = max_order;
00130   
00131   // compute the list of total number of coefficients for p-th order expansion
00132   int limit = 2 * max_order + 1;
00133   list_total_num_coeffs_.Init(limit);
00134   for(p = 0; p < limit; p++) {
00135     list_total_num_coeffs_[p] = (int) math::BinomialCoefficient(p + dim, dim);
00136   }
00137 
00138   // compute factorials
00139   ComputeFactorials();
00140 
00141   // allocate space for inverse factorial and 
00142   // negative inverse factorials and multiindex mapping and n_choose_k 
00143   // and multiindex_combination precomputed factors
00144   inv_multiindex_factorials_.Init(list_total_num_coeffs_[limit - 1]);  
00145   neg_inv_multiindex_factorials_.Init(list_total_num_coeffs_[limit - 1]);
00146   multiindex_mapping_.Init(list_total_num_coeffs_[limit - 1]);
00147   (multiindex_mapping_[0]).Init(dim_);
00148   for(j = 0; j < dim; j++) {
00149     (multiindex_mapping_[0])[j] = 0;
00150   }
00151   n_choose_k_.Init((limit - 1) + dim + 1, (limit - 1) + dim + 1);
00152   n_choose_k_.SetZero();
00153 
00154   // initialization of temporary variables for computation...
00155   heads.Init(dim + 1);
00156   cinds.Init(list_total_num_coeffs_[limit - 1]);
00157 
00158   for(i = 0; i < dim; i++) {
00159     heads[i] = 0;
00160   }
00161   heads[dim] = INT_MAX;
00162   cinds[0] = 0;
00163   
00164   // compute inverse factorial and negative inverse factorials and
00165   // multiindex mappings...
00166   inv_multiindex_factorials_[0] = 1.0;
00167   neg_inv_multiindex_factorials_[0] = 1.0;
00168   for(k = 1, t = 1, tail = 1; k <= 2 * max_order_; k++, tail = t) {
00169     for(i = 0; i < dim; i++) {
00170       int head = (int) heads[i];
00171       heads[i] = t;
00172       for(j = head; j < tail; j++, t++) {
00173         cinds[t] = (j < heads[i + 1]) ? cinds[j] + 1 : 1;
00174         inv_multiindex_factorials_[t] = 
00175           inv_multiindex_factorials_[j] / cinds[t];
00176         neg_inv_multiindex_factorials_[t] =
00177           -neg_inv_multiindex_factorials_[j] / cinds[t];
00178         
00179         (multiindex_mapping_[t]).InitCopy(multiindex_mapping_[j]);
00180         (multiindex_mapping_[t])[i] = (multiindex_mapping_[t])[i] + 1;
00181       }
00182     }
00183   }
00184 
00185   // compute n choose k's
00186   for(j = 0; j <= 2 * max_order + dim; j++) {
00187     for(k = 0; k <= 2 * max_order + dim; k++) {
00188       n_choose_k_.set(j, k, math::BinomialCoefficient(j, k));
00189     }
00190   }
00191 
00192   // initialize multiindex_combination matrix beta choose alpha
00193   ComputeMultiindexCombination();
00194 
00195   // compute the lower_mapping_index_ and the upper_mapping_index_
00196   // (see series_expansion_aux.h for explanation)
00197   ComputeLowerMappingIndex();
00198   ComputeUpperMappingIndex();
00199 }
00200 
00201 void SeriesExpansionAux::PrintDebug(const char *name, FILE *stream) const {
00202 
00203   fprintf(stream, "----- SERIESEXPANSIONAUX %s ------\n", name);
00204   fprintf(stream, "Max order: %d, dimension: %d\n", max_order_, dim_);
00205 
00206   fprintf(stream, "Multiindex mapping: ");
00207   for (index_t i = 0; i < multiindex_mapping_.size(); i++) {
00208 
00209     DEBUG_ASSERT_MSG(ComputeMultiindexPosition(multiindex_mapping_[i]) == i,
00210                      "REIMPLEMENT ComputeMultiindexPosition function!");
00211     fprintf(stream, "( ");
00212     for(index_t j = 0; j < dim_; j++) {
00213       fprintf(stream, "%d ", multiindex_mapping_[i][j]);
00214     }
00215     fprintf(stream, "): %g %g ", inv_multiindex_factorials_[i],
00216             neg_inv_multiindex_factorials_[i]);
00217   }
00218   fprintf(stream, "\n");
00219 }
Generated on Mon Jan 24 12:04:38 2011 for FASTlib by  doxygen 1.6.3