# ifdef ANSI_HEADERS # include # include # include # else # include # include # include # endif # include # include # include using namespace std; # include "fsu.hpp" //****************************************************************************80 void fsu_halton ( int dim_num, int n, int step, int seed[], int leap[], int base[], double r[] ) //****************************************************************************80 // // Purpose: // // FSU_HALTON computes N elements of a leaped Halton subsequence. // // License: // // Copyright (C) 2004 John Burkardt and Max Gunzburger // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // Discussion: // // The DIM_NUM-dimensional Halton sequence is really DIM_NUM separate // sequences, each generated by a particular base. // // This routine selects elements of a "leaped" subsequence of the // Halton sequence. The subsequence elements are indexed by a // quantity called STEP, which starts at 0. The STEP-th subsequence // element is simply element // // SEED(1:DIM_NUM) + STEP * LEAP(1:DIM_NUM) // // of the original Halton sequence. // // // The data to be computed has two dimensions. // // The number of data items is DIM_NUM * N, where DIM_NUM is the spatial dimension // of each element of the sequence, and N is the number of elements of the sequence. // // The data is stored in a one dimensional array R. The first element of the // sequence is stored in the first DIM_NUM entries of R, followed by the DIM_NUM entries // of the second element, and so on. // // In particular, the J-th element of the sequence is stored in entries // 0+(J-1)*DIM_NUM through (DIM_NUM-1) + (J-1)*DIM_NUM. // // Modified: // // 10 November 2006 // // Author: // // John Burkardt // // Reference: // // J H Halton, // On the efficiency of certain quasi-random sequences of points // in evaluating multi-dimensional integrals, // Numerische Mathematik, // Volume 2, 1960, pages 84-90. // // J H Halton and G B Smith, // Algorithm 247: Radical-Inverse Quasi-Random Point Sequence, // Communications of the ACM, // Volume 7, 1964, pages 701-702. // // Ladislav Kocis and William Whiten, // Computational Investigations of Low-Discrepancy Sequences, // ACM Transactions on Mathematical Software, // Volume 23, Number 2, 1997, pages 266-294. // // Parameters: // // Input, int DIM_NUM, the spatial dimension. // // Input, int N, the number of elements of the sequence. // // Input, int STEP, the index of the subsequence element. // 0 <= STEP is required // // Input, int SEED[DIM_NUM], the Halton sequence index corresponding // to STEP = 0. // // Input, int LEAP[DIM_NUM], the succesive jumps in the Halton sequence. // // Input, int BASE[DIM_NUM], the Halton bases. // // Output, double R[DIM_NUM*N], the next N elements of the // leaped Halton subsequence, beginning with element STEP. // { double base_inv; int digit; int i; int j; int *seed2; // // Check the input. // if ( !halham_dim_num_check ( dim_num ) ) { exit ( 1 ); } if ( !halham_n_check ( n ) ) { exit ( 1 ); } if ( !halham_step_check ( step ) ) { exit ( 1 ); } if ( !halham_seed_check ( dim_num, seed ) ) { exit ( 1 ); } if ( !halham_leap_check ( dim_num, leap ) ) { exit ( 1 ); } if ( !halton_base_check ( dim_num, base ) ) { exit ( 1 ); } // // Calculate the data. // seed2 = new int[n]; for ( i = 0; i < dim_num; i++ ) { for ( j = 0; j < n; j++ ) { seed2[j] = seed[i] + ( step + j ) * leap[i]; } for ( j = 0; j < n; j++ ) { r[i+j*dim_num] = 0.0E+00; } for ( j = 0; j < n; j++ ) { base_inv = 1.0E+00 / ( ( double ) base[i] ); while ( seed2[j] != 0 ) { digit = seed2[j] % base[i]; r[i+j*dim_num] = r[i+j*dim_num] + ( ( double ) digit ) * base_inv; base_inv = base_inv / ( ( double ) base[i] ); seed2[j] = seed2[j] / base[i]; } } } delete [] seed2; return; } //****************************************************************************80 bool halton_base_check ( int dim_num, int base[] ) //****************************************************************************80 // // Purpose: // // HALTON_BASE_CHECK is TRUE if BASE is legal. // // License: // // Copyright (C) 2004 John Burkardt and Max Gunzburger // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // Modified: // // 10 November 2006 // // Author: // // John Burkardt // // Parameters: // // Input, int DIM_NUM, the spatial dimension. // // Input, int BASE[DIM_NUM], the bases. // // Output, bool HALTON_BASE_CHECK, is true if BASE is legal. // { int i; bool value; value = true; for ( i = 0; i < dim_num; i++ ) { if ( base[i] <= 1 ) { cout << "\n"; cout << "HALTON_BASE_CHECK - Fatal error!\n"; cout << " Bases must be greater than 1.\n"; cout << " base[" << i << "] = " << base[i] << "\n"; value = false; break; } } return value; }