mult_series_expansion_aux.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00035 #ifndef MULT_SERIES_EXPANSION_AUX_H
00036 #define MULT_SERIES_EXPANSION_AUX_H
00037
00038 #include "fastlib/fastlib.h"
00039
00044 class MultSeriesExpansionAux {
00045
00046 public:
00047
00048 int dim_;
00049
00050 int max_order_;
00051
00052 Vector factorials_;
00053
00054 ArrayList<int> list_total_num_coeffs_;
00055
00056 Vector inv_multiindex_factorials_;
00057
00058 Vector neg_inv_multiindex_factorials_;
00059
00060 Matrix multiindex_combination_;
00061
00062 ArrayList< ArrayList<int> > multiindex_mapping_;
00063
00069 ArrayList< ArrayList<int> > lower_mapping_index_;
00070
00076 ArrayList< ArrayList<int> > upper_mapping_index_;
00077
00079 Matrix n_choose_k_;
00080
00085 ArrayList< ArrayList<int> > traversal_mapping_;
00086
00087 OT_DEF_BASIC(MultSeriesExpansionAux) {
00088 OT_MY_OBJECT(dim_);
00089 OT_MY_OBJECT(max_order_);
00090 OT_MY_OBJECT(factorials_);
00091 OT_MY_OBJECT(list_total_num_coeffs_);
00092 OT_MY_OBJECT(inv_multiindex_factorials_);
00093 OT_MY_OBJECT(neg_inv_multiindex_factorials_);
00094 OT_MY_OBJECT(multiindex_combination_);
00095 OT_MY_OBJECT(multiindex_mapping_);
00096 OT_MY_OBJECT(lower_mapping_index_);
00097 OT_MY_OBJECT(upper_mapping_index_);
00098 OT_MY_OBJECT(n_choose_k_);
00099 OT_MY_OBJECT(traversal_mapping_);
00100 }
00101
00102 public:
00103
00104 void ComputeFactorials() {
00105 factorials_.Init(2 * max_order_ + 1);
00106
00107 factorials_[0] = 1;
00108 for(index_t t = 1; t < factorials_.length(); t++) {
00109 factorials_[t] = t * factorials_[t - 1];
00110 }
00111 }
00112
00113 void ComputeTraversalMapping() {
00114
00115
00116 int limit = 2 * max_order_;
00117 traversal_mapping_.Init(limit + 1);
00118
00119 for(index_t i = 0; i <= max_order_; i++) {
00120
00121 traversal_mapping_[i].Init();
00122
00123 for(index_t j = 0; j < list_total_num_coeffs_[limit]; j++) {
00124
00125 const ArrayList<int> &mapping = multiindex_mapping_[j];
00126 int flag = 0;
00127
00128 for(index_t d = 0; d < dim_; d++) {
00129 if(mapping[d] > i) {
00130 flag = 1;
00131 break;
00132 }
00133 }
00134
00135 if(flag == 0) {
00136 (traversal_mapping_[i]).PushBackCopy(j);
00137 }
00138 }
00139 }
00140 }
00141
00142 void ComputeLowerMappingIndex() {
00143
00144 ArrayList<int> diff;
00145 diff.Init(dim_);
00146
00147
00148 int limit = 2 * max_order_;
00149 lower_mapping_index_.Init(list_total_num_coeffs_[limit]);
00150
00151 for(index_t i = 0; i < list_total_num_coeffs_[limit]; i++) {
00152 const ArrayList<int> &outer_mapping = multiindex_mapping_[i];
00153 lower_mapping_index_[i].Init();
00154
00155 for(index_t j = 0; j < list_total_num_coeffs_[limit]; j++) {
00156 const ArrayList<int> &inner_mapping = multiindex_mapping_[j];
00157 int flag = 0;
00158
00159 for(index_t d = 0; d < dim_; d++) {
00160 diff[d] = outer_mapping[d] - inner_mapping[d];
00161
00162 if(diff[d] < 0) {
00163 flag = 1;
00164 break;
00165 }
00166 }
00167
00168 if(flag == 0) {
00169 (lower_mapping_index_[i]).PushBackCopy(j);
00170 }
00171 }
00172 }
00173 }
00174
00175 void ComputeMultiindexCombination() {
00176
00177 int limit = 2 * max_order_;
00178 multiindex_combination_.Init(list_total_num_coeffs_[limit],
00179 list_total_num_coeffs_[limit]);
00180
00181 for(index_t j = 0; j < list_total_num_coeffs_[limit]; j++) {
00182
00183
00184 const ArrayList<int> &beta_mapping = multiindex_mapping_[j];
00185
00186 for(index_t k = 0; k < list_total_num_coeffs_[limit]; k++) {
00187
00188
00189 const ArrayList<int> &alpha_mapping = multiindex_mapping_[k];
00190
00191
00192 multiindex_combination_.set(j, k, 1);
00193
00194 for(index_t i = 0; i < dim_; i++) {
00195 multiindex_combination_.set
00196 (j, k, multiindex_combination_.get(j, k) *
00197 n_choose_k_.get(beta_mapping[i], alpha_mapping[i]));
00198
00199 if(multiindex_combination_.get(j, k) == 0)
00200 break;
00201 }
00202 }
00203 }
00204 }
00205
00206 void ComputeUpperMappingIndex() {
00207
00208 ArrayList<int> diff;
00209 diff.Init(dim_);
00210
00211
00212 int limit = 2 * max_order_;
00213 upper_mapping_index_.Init(list_total_num_coeffs_[limit]);
00214
00215 for(index_t i = 0; i < list_total_num_coeffs_[limit]; i++) {
00216 const ArrayList<int> &outer_mapping = multiindex_mapping_[i];
00217 upper_mapping_index_[i].Init();
00218
00219 for(index_t j = 0; j < list_total_num_coeffs_[limit]; j++) {
00220 const ArrayList<int> &inner_mapping = multiindex_mapping_[j];
00221 int flag = 0;
00222
00223 for(index_t d = 0; d < dim_; d++) {
00224 diff[d] = inner_mapping[d] - outer_mapping[d];
00225
00226 if(diff[d] < 0) {
00227 flag = 1;
00228 break;
00229 }
00230 }
00231
00232 if(flag == 0) {
00233 (upper_mapping_index_[i]).PushBackCopy(j);
00234 }
00235 }
00236 }
00237 }
00238
00239
00240 double factorial(int k) const { return factorials_[k]; }
00241
00242 int get_dimension() const { return dim_; }
00243
00244 int get_total_num_coeffs(int order) const {
00245 return list_total_num_coeffs_[order];
00246 }
00247
00248 int get_max_total_num_coeffs() const {
00249 return list_total_num_coeffs_[max_order_];
00250 }
00251
00252 const Vector& get_inv_multiindex_factorials() const {
00253 return inv_multiindex_factorials_;
00254 }
00255
00256 const ArrayList< int > * get_lower_mapping_index() const {
00257 return lower_mapping_index_.begin();
00258 }
00259
00260 int get_max_order() const {
00261 return max_order_;
00262 }
00263
00264 const ArrayList< int > & get_multiindex(int pos) const {
00265 return multiindex_mapping_[pos];
00266 }
00267
00268 const ArrayList< int > * get_multiindex_mapping() const {
00269 return multiindex_mapping_.begin();
00270 }
00271
00272 const Vector& get_neg_inv_multiindex_factorials() const {
00273 return neg_inv_multiindex_factorials_;
00274 }
00275
00276 double get_n_choose_k(int n, int k) const {
00277 return n_choose_k_.get(n, (int) math::ClampNonNegative(k));
00278 }
00279
00280 double get_n_multichoose_k_by_pos(int n, int k) const {
00281 return multiindex_combination_.get(n, k);
00282 }
00283
00284 const ArrayList< int > * get_upper_mapping_index() const {
00285 return upper_mapping_index_.begin();
00286 }
00287
00288
00289
00293 int ComputeMultiindexPosition(const ArrayList<int> &multiindex) const {
00294 int index = 0;
00295
00296
00297 for(index_t i = 0; i < dim_; i++) {
00298 index *= (2 * max_order_ + 1);
00299 index += multiindex[i];
00300 }
00301 return index;
00302 }
00303
00307 double FarFieldEvaluationCost(int order) const {
00308 return pow(order + 1, dim_);
00309 }
00310
00314 double FarFieldToLocalTranslationCost(int order) const {
00315 return pow(order + 1, 2 * dim_);
00316 }
00317
00321 double DirectLocalAccumulationCost(int order) const {
00322 return pow(order + 1, dim_);
00323 }
00324
00329 void Init(int max_order, int dim) {
00330
00331
00332 dim_ = dim;
00333 max_order_ = max_order;
00334
00335
00336
00337 int limit = 2 * max_order_;
00338 list_total_num_coeffs_.Init(limit + 1);
00339 list_total_num_coeffs_[0] = 1;
00340 for(index_t p = 1; p <= limit; p++) {
00341 list_total_num_coeffs_[p] = (int) pow(p + 1, dim);
00342 }
00343
00344
00345 ComputeFactorials();
00346
00347
00348
00349
00350 inv_multiindex_factorials_.Init(list_total_num_coeffs_[limit]);
00351 neg_inv_multiindex_factorials_.Init(list_total_num_coeffs_[limit]);
00352 multiindex_mapping_.Init(list_total_num_coeffs_[limit]);
00353 (multiindex_mapping_[0]).Init(dim_);
00354 for(index_t j = 0; j < dim; j++) {
00355 (multiindex_mapping_[0])[j] = 0;
00356 }
00357 n_choose_k_.Init(dim * (limit + 1), dim * (limit + 1));
00358 n_choose_k_.SetZero();
00359
00360
00361
00362 inv_multiindex_factorials_[0] = 1.0;
00363 neg_inv_multiindex_factorials_[0] = 1.0;
00364 if(max_order > 0) {
00365 index_t boundary, i, k, step;
00366
00367 for(boundary = list_total_num_coeffs_[limit], k = 0,
00368 step = list_total_num_coeffs_[limit] / (limit + 1);
00369 step >= 1; step /= (limit + 1),
00370 boundary /= (limit + 1), k++) {
00371
00372 for(i = 0; i < list_total_num_coeffs_[limit]; ) {
00373 int inner_limit = i + boundary;
00374 int div = 1;
00375
00376 i += step;
00377
00378 for( ; i < inner_limit; i += step) {
00379
00380 inv_multiindex_factorials_[i] =
00381 inv_multiindex_factorials_[i - step] / div;
00382 neg_inv_multiindex_factorials_[i] =
00383 -neg_inv_multiindex_factorials_[i - step] / div;
00384 div++;
00385
00386
00387 multiindex_mapping_[i].InitCopy(multiindex_mapping_[i - step]);
00388 (multiindex_mapping_[i])[k] = (multiindex_mapping_[i])[k] + 1;
00389 }
00390 }
00391 }
00392 }
00393
00394
00395 for(index_t j = 0; j < n_choose_k_.n_rows(); j++) {
00396 for(index_t k = 0; k < n_choose_k_.n_cols(); k++) {
00397 n_choose_k_.set(j, k, math::BinomialCoefficient(j, k));
00398 }
00399 }
00400
00401
00402 ComputeMultiindexCombination();
00403
00404
00405
00406 ComputeLowerMappingIndex();
00407 ComputeUpperMappingIndex();
00408
00409
00410 ComputeTraversalMapping();
00411 }
00412
00416 void PrintDebug(const char *name="", FILE *stream=stderr) const {
00417 fprintf(stream, "----- SERIESEXPANSIONAUX %s ------\n", name);
00418 fprintf(stream, "Max order: %d, dimension: %d\n", max_order_, dim_);
00419
00420 fprintf(stream, "Multiindex mapping: ");
00421 for (index_t i = 0; i < multiindex_mapping_.size(); i++) {
00422
00423 DEBUG_ASSERT_MSG(ComputeMultiindexPosition(multiindex_mapping_[i]) == i,
00424 "REIMPLEMENT ComputeMultiindexPosition function!");
00425 fprintf(stream, "( ");
00426 for(index_t j = 0; j < dim_; j++) {
00427 fprintf(stream, "%d ", multiindex_mapping_[i][j]);
00428 }
00429 fprintf(stream, "): %g %g ", inv_multiindex_factorials_[i],
00430 neg_inv_multiindex_factorials_[i]);
00431 }
00432 fprintf(stream, "\n");
00433 }
00434
00435 };
00436
00437 #endif