Post on 13-Sep-2018
METODOS NUMERICOS PARA CALCULAR INTEGRALES MULTIDIMENSIONALES
ILIA D. MIKHAILOV
JAVIER BETANCUR C.
ESCUELA DE FISICA
FACULTAD DE CIENCIAS
UNIVERSIDAD INDUSTRIAL DE SANTANDER
Bucaramanga, Abril de 1996
CONTENIDO
I. INTRODUCCIÓN 1
II. ALGORITMOS AUTOADAPTABLES PARA CALCULAR INTEGRALES UNIDIMENSIONALES.
2.1 Fórmulas de Newton-Cotes
2.2. Fórmulas de Gauss
2.3 Algoritmos Autoadaptables para Fórmulas de Cuadraturas
2.4 Programa QNC3
2.5. Programa QNC7
2.6. Programa QNC9
2.7. Programa GAUS8
III. FORMULAS DE CUADRATURAS EN D DIMENSIONES
3.1 Reducción de una Integral Múltiple a otra Reiterada. Programa REITER
3.2 Fórmulas de Cuadraturas de Newton-Cotes en D Dimensiones para un Hiperrectángulo
IV. METODO DE MONTE-CARLO
4.1 Método Monte-Carlo Simple
4.2 Método Monte-Carlo Geométrico
4.3 Programa Autoadaptable de Monte-Carlo
V. CONCLUSION
BIBLIOGRAFIA
I. INTRODUCCIÓN
Es de gran interés práctico, elaborar métodos aproximados para resolver la ecuación de Schrödinger para muchas partículas,
(átomos y moléculas). Entre los métodos aproximados actuales tenemos: a) Aproximación de Hartree-Fock; b) teoría de
perturbaciones; c) método variacional y d) método cuántico de Monte-Carlo. Cada uno de estos métodos, tiene sus ventajas y
desventajas, pero todos conducen a cálculos muy voluminosos y difíciles de encontrar repetidamente los valores de las
integrales multidimensionales, debido a la interacción electrón-electrón. Estas integrales en general son 6-dimensionales y
tienen la siguiente forma:
I dr dr F r r r12 1 2 1 2 1 2
, , , (1.1)
donde r1 y
r2 son vectores del primero y segundo electrón y
r1 2, es la distancia entre ellos (
r r r1 2 1 2, ).
Es muy importante asegurar que los cálculos de la integrales para todos los posibles valores de los parámetros variacionales
garantizan una precisión aceptable. Existen dos maneras para cumplir la condición anterior. La primera aumentando el
número de pasos, en los cuales se calcula la función y de esta manera aumentan sin límites, (especialmente para las integrales
multidimensionales), el tiempo de computación. Una segunda posibilidad es aplicar algoritmos autoadaptables. En estos
algoritmos, los tamaños de las subregiones se definen automáticamente: Tamaños grandes, donde la función es suave y se
cambia lentamente, y pequeños en las partes donde la función varía bruscamente. De esta manera, se obtiene un resultado con
buena precisión en un tiempo mínimo de computación.
2
El primer programa autoadaptable [1], para calcular integrales unidimensionales fue publicado en 1962 y empleó la fórmula
de cuadratura de Simpson. Este programa y sus modificaciones [2-4] tuvieron éxitos en la práctica y fueron incorporados en
diferentes software (Matlab, Matemática, etc.). El usuario de estos programas, define un intervalo [a,b] y prepara el
subprograma, para calcular la función f(x) en cualquier punto de este intervalo y escoge la precisión deseada. El programa
trata de encontrar el valor de I, para el cual se cumple la siguiente relación,
I f x dxa
b ( ) , (1.2)
durante un tiempo mínimo. El programa puede concluir, que la precisión deseada es imposible y encontrar su mejor valor
posible y comunicar la precisión alcanzada.
La precisión alcanzada y el tiempo de computación de un programa autoadaptable, dependen de las fórmulas de cuadraturas
que se utilicen en el programa. En el capítulo II, se consideran dos tipos de fórmulas de cuadraturas, para calcular integrales
unidimensionales: Un algoritmo utiliza la red con nodos equidistantes (Newton-Cotes) y otro la red de nodos no equidistantes
(de Gauss).
Para elaborar algoritmos autoadaptables, en el cálculo de integrales bi- y tridimensionales una de las posibilidades consiste en
reducir la integral multidimensional a otra repetida, para la cual se puede aplicar sucesivamente los algoritmos autoadaptables
unidimensionales. Otra posibilidad, consiste en la deducción directa de fórmulas de cuadraturas para un hiperrectángulo
multidimensional y con base en éste construir un algoritmo autoadaptable. Ambas posibilidades se consideran en el capítulo
III.
Las fórmulas de cuadraturas sobre las redes con nodos equidistantes, se usan en la práctica sólo para espacios uni- bi- y
tridimensionales, ya que con el aumento de la dimensión del espacio, el tiempo de computación crece catastróficamente.
El método de Monte-Carlo, se usa en espacios con dimensión mayor a 4, en el cual, la integral, f r dF r dr( ) ( )
, se calcula
como un valor promedio, f r Ni
i
N
( ) /
1
, de un conjunto de puntos, ri , los cuales, son generados a través de un generador de
vectores aleatorios, con función de distribución F r(
), dada. Este método en el caso de integrales multidimensionales, tiene
varias ventajas en comparación con los algoritmos que utilizan las fórmulas de cuadraturas: a) El algoritmo es muy sencillo;
b) el error del método usado no crece cuando la dimensión espacial aumenta; c) los cálculos realizados se utilizan
completamente en las etapas siguientes; d) la estimación de errores es muy sencilla. En el capítulo IV, consideramos
diferentes algoritmos de realización del método Monte-Carlo y un algoritmo autoadaptable para calcular integrales
multidimensionales a través del método Monte-Carlo.
II. ALGORITMOS AUTOADAPTABLES PARA CALCULARINTEGRALES UNIDIMENSIONALES.
Para calcular integrales unidimensionales se utilizan las fórmulas de cuadraturas:
f x dx W f x f nk k
k
n
a
b( ) ( ) ( , )
1
(2.1)
donde los Wk se llaman, los coeficientes, xk son los nodos de la fórmula y (f,n), es el error de la fórmula, el cual depende del
número de nodos y de la función, f(x). Para deducir las fórmulas (2.1), existen dos posibilidades. Una es elegir los
nodos equidistantes, (xk = a + kh; k = 0, 1, 2, ..., n; h = (b - a)/n) y encontrar los coeficientes Wk, de la condición (Pn, f) =
0, para cualquier polinomio hasta del orden n. Estas fórmulas obtenidas por medio de la integración de polinomios de
interpolación, se llaman fórmulas de Newton-Cotes. Por ejemplo, las fórmulas conocidas de rectángulos, trapecios, y de
Simpson, se obtienen a través de integración de polinomios de interpolación de orden nulo, primero y de segundo orden,
respectivamente. Otra posibilidad, consiste en elegir los nodos, xi y coeficientes Wi, de tal manera, que la fórmula sea exacta,
para un polinomio de orden máximo. Como el número de parámetros incógnitos, es igual a 2n, esta condición se puede
3
cumplir para polinomios hasta del orden 2n-1, (x0, x1, x2, ..., x2n-1), es decir, (P2n-1,n)=0 para cualquier polinomio P2n-1(x).
De esta manera se deducen las fórmulas de cuadratura de Gauss.
En los párrafos 2.1 y 2.2 hacemos una revisión breve de estos dos métodos. El método de Rounge, para estimar el error del
cálculo, y su explicación para construir algoritmos autoadaptables, para calcular integrales unidimensionales, se consideran en
el párrafo 2.3.
2.1 Fórmulas de Newton-Cotes
Para obtener las fórmulas (2.1), independientes del intervalo [a,b] usamos el cambio de variables, t = (x - a)/(b - a)
g x dx b a f t dt W fk
nf n f t g a b a t
a
b
k
k
n
( ) ( ) ( ) ( , ) ; ( ) ( ( ) )
0
0
1
(2.2)
y denotamos yk = f(k/n), k = 0, 1, 2, ..., n, n es el número de subdivisiones en el segmento [0,1]. Para encontrar los
coeficientes, Wk en la fórmula (2.2), sustituiremos a f(t), por un polinomio de interpolación de Lagrange de orden n, de tal
forma que, en los puntos tk = k/n, tome valores, de yk = f(tk), k = 0, 1, 2, ..., n.
f t P t y f nk k
k
n
( ) ( ) ( , )
1
P t
t t t t t t t t t t
t t t t t t t t t tk
k k n
k k k k k k k n
( )... ...
... ...
0 1 1 1
0 1 1 1
(2.3)
Haciendo en la integral otro cambio de variables, t = q/n, encontramos la expresión final para los coeficientes de Cotes, Wk:
Wn k n k
q i dqk
n k
ii k
nn
1 1
10
( )
!( )!( ) (2.4)
Estos coeficientes satisfacen, dos condiciones:
Wk
k
n
10
y Wk = Wn-k (2.5)
De las fórmulas de Newton-Cotes, (2.2 y 2.4), se puede demostrar teóricamente que el error (f,n), decrece con el aumento del
número de subdivisiones n, según la relación siguiente:
(f,n)c
n P ; P
n
2
22 (2.6)
donde n
2
es la parte entera de la fracción n/2.
Tabla 2.1. Parámetros de las fórmulas de Newton-Cotes
n ~W0
~W1
~W2
~W3
~W4
~W5
~W6
~W7
~W8 N P
1 1 1 2 2
2 1 4 1 6 4
3 1 3 3 1 8 4
4 7 32 12 32 7 90 6
5 19 75 50 50 75 19 288 6
6 41 216 27 272 27 216 41 840 8
7 751 3577 1323 2989 2989 1323 3577 751 17280 8
8 989 5888 -928 10496 -4540 10496 -928 5888 989 28350 10
En la Tabla 2.1, presentamos los coeficientes normalizados de Cotes, Wk,
4
WW
Nk
k
~
(2.7)
y los valores de P de la fórmula (2.6).
2.2. Fórmulas de Gauss
Para deducir las fórmulas de Gauss, consideremos inicialmente la integral:
f t dt W f t f nk k
k
n
( ) ( ) ( , )
11
1
(2.8)
y encontremos los nodos tk, usando las n condiciones,
t P t dt W t P ti
n k k
i
n k
k
n
( ) ( )
1
1
1
, i = 0, 1, 2, ..., n-1 (2.9)
donde Pn(t) es un polinomio de Legendre de orden n. La condición (2.9), garantiza que el error de la fórmula de cuadratura
(2.8), para n polinomios, tiPn(t), será igual a cero. Los ti que son ortogonales con Pn(t), puesto que se pueden representar
como combinación lineal de los polinomios de Legendre hasta el orden i. De esta manera la integral (2.9) es igual a cero.
Para satisfacer esta condición es suficiente hacer,
Pn(tk) = 0 , k = 0, 1, 2, ..., n-1 (2.10)
tomando como nodos, tk en la fórmula (2.8) los n ceros del polinomio de Legendre del orden n. Las otras n ecuaciones, para
los coeficiente, Wk se obtienen al suponer que la fórmula (2.8) es exacta ( = 0) para n funciones ti; i = 0, 1, 2, ..., n-1,
W t
ii impar
i par
k ki
k
n
2
1
01
; ,
; ,
(2.11)
En la tabla 2.2 se presentan los coeficiente Wk y los nodos tk , para la fórmula de Gauss, con n = 8 nodos.
Tabla 2.2. Parámetros de las Fórmulas de Cuadraturas de Gauss, para n = 8
k tk Wk
1; 8 0.96028986 0.10122854
2; 7 0.79666648 0.22238104
3; 6 0.52553242 0.31370664
4; 5 0.18343464 0.36268378
Para el caso general de una integral, dentro del intervalo (a,b), hacemos el siguiente cambio de variables,
xa b b a
t
2 2, las cuales reducen la integral, (2.8) y la fórmula de cuadraturas de Gauss, así:
f x dxb a
W fb a b a
t f nk k
k
n
a
b
( ) ( , )
2 2 21
(2.12)
Se puede demostrar, que el error , en (2.12), es igual:
( , )( ) ( !)
[( )!] ( )( )( )f n
b a n
n nf
nn
2 1 4
3
2
2 2 1 ; a b (2.13)
2.3 Algoritmos Autoadaptables para Fórmulas de Cuadraturas
5
En la práctica para calcular la integral en un intervalo [a,b] se divide, en subintervalos [x i, xi+1]. La mayoría de los
programas utilizan el proceso de bisección recursivo. El número de subintervalos, sus disposiciones y longitudes, dependen de
la función f(x) y de la precisión deseada. Denotemos a x1 = a; xn+1 = b y h = xi+1 - xi, donde n es el número de intervalos.
En los algoritmos autoadaptables, a cada subintervalo se le aplica la fórmula de cuadraturas, dos veces, para n y 2n divisiones.
Estos dos resultados se denotan, por I n
i y I n
i
2 . Por ejemplo, el algoritmo autoadaptable, para las fórmulas de cuadraturas de
Simpson (Newton-Cotes de orden 3, programa QNC3), utilizan la fórmula principal (dos subintervalos):
Ih
f x f xh
f x hn
i i
i i
i
i i
64
2( ) ( ) (2.14)
y la fórmula combinada (cuatro subintervalos)
Ih
f x f xh
f xh
f xh
f x hn
i i
i i
i
i
i
i
i
i i212
44
22
43
4
( ) ( ) (2.15)
Las expresiones (2.14) y (2.15) dan valores aproximados de la integral
I f x dxi
x
x
i
i
( )1
(2.16)
La idea principal de los algoritmos autoadaptables, consiste en comparar dos aproximaciones I n
i y I n
i
2 y estimar sus
precisiones. Si en esta comparación, se encuentra que la precisión es aceptable, entonces uno de estos valores, se toma como
el valor de la integral, dentro del intervalo [xi, xi+1], en caso contrario, el proceso de bisección continúa.
El número total de accesos a la función, se disminuye debido a que las fórmulas (2.14) y (2.15), utilizan los valores de la
función en algunos puntos comunes. Por ejemplo, en el caso de la fórmula de Simpson, los I n
i
2 , necesitan cinco valores de la
función, pero tres de los cuales, se usan también en I n
i. Por eso, el tratamiento del nuevo intervalo, necesita solo, dos
cálculos adicionales de valores de la función.
Denotando el valor exacto de la integral I i para cuadraturas de orden p, tenemos:
I Ich
nn
i i i
p I I
ch
nn
i i i
pi2
2
( ) (2.17)
Excluyendo de estas dos igualdades la constante c desconocida, se obtiene:
I I I In
i i
p n
i
n
i
2 2
1
2 1
(2.18)
es decir, el error de cálculo, I n
i
2 es 2p-1 veces menor, que la diferencia entre las dos aproximaciones sucesivas, I n
i y I n
i
2 .
La operación principal de un programa autoadaptable, consiste en la bisección de cada subintervalo, hasta que cumpla la
condición
1
2 12p n
i
n
i iI Ih
b a
(2.19)
donde es la precisión deseada y definida por el usuario. Si todos los subintervalos satisfacen la condición (2.19), el
programa da el resultado
I In n
i
i
n
2 2
1
,
el cual se puede tomar como el valor de la integral ya que según, (2.18) y (2.19)
I f x dx I I I I I Ib a
hna
b
n
i i
i
n
n
i i
i
n
p n
i
n
i
i
n
p
p
i
i
n
2 2
1
2
1
2
1 1
1
2 1
1
2 1
2 1
( )
6
Las fórmulas (2.17) permiten calcular la integral con una precisión mayor. Combinando las fórmulas (2.17) con la integral
I n
i
2 , después de excluir c, se obtiene la fórmula
I II I
i n
i n
i
n
i
p
2
2
2 1 (2.20)
la cual es llamada Fórmula de Extrapolación de Richardson.
El algoritmo autoadaptable de cálculo, tiene una estructura recursiva en forma de árbol binario. Cada intervalo, se divide en
dos partes y la integral se calcula dos veces: la primera para todo el intervalo y la segunda como suma de dos integrales, para
los subintervalos. Si estos dos valores satisfacen la condición (2.18), entonces el proceso se detiene. En caso contrario, el
procedimiento se repite, primero, para el subintervalo izquierdo y después para el derecho.
La figura 2.1, presenta el funcionamiento típico de un programa autoadaptable, para la función
f xx x
( )( . ) . ( . ) .
1
0 3 0 01
1
0 9 0 046
2 2
dentro del intervalo [0,1]. Al programa se le adicionaron subprogramas para graficar todos los puntos {xi, f(xi)} y {xi, 0}, i =
1, 2, ...,n en los cuales se calculan los valores de la función para satisfacer la precisión deseada. La función bajo el signo de
la integral, tiene un máximo absoluto en x = 0.3 y otro máximo relativo en x = 0.9. La figura muestra que el programa hace
los subintervalos pequeños cerca a los máximos y grandes, lejos de éstos. Tal comportamiento es típico de todos los
programas autoadaptables, los cuales alcanzan la misma precisión de los no autoadaptables, pero en menos tiempo de
computación.
Al final del capítulo presentamos textos de cuatro programas autoadaptables: QNC3, QNC7 y QNC9 para las fórmulas de
cuadraturas de Newton-Cotes con 3, 7 y 9 nodos y GAUS8 con fórmulas de cuadraturas de Gauss con 8 nodos. Los
comentarios de los textos explican su funcionamiento y significado de los parámetros de entrada y de salida. Nosotros
realizamos una serie de simulaciones, que demostraron las ventajas de los programas QNC7 y QNC9, los cuales alcanzan una
precisión deseada con un mínimo de accesos al subprograma. En el capítulo III usamos estos dos programas como base para
calcular integrales múltiples.
2.4 Programa QNC3
SUBROUTINE QNC3 (FUN,A,B,ERR,ANS,IERR)
C PROGRAMA PARA CALCULAR INTEGRALES USANDO
C ALGORITMOS AUTOADAPTABLES FORMULAS DE CUADRATURAS
C DE NEWTON - COTES Y CON TRES NUDOS (SIMPSON)
C SE USA EL PROCEDIMIENTO RECURSIVO DE BISECCION DE LOS
C INTERVALOS PARA CONTROLAR AUTOMATICAMENTE
C LA PRECISION DESEADA.
C
7
C DESCRIPCION DE ARGUMENTOS DE ENTRADA:
C -----------------------------------------------------------------------------
C FUN - FUNCION A INTEGRAR. DEBE SER DEFINIDA POR EL USUARIO .
C EN EL PROGRAMA PRINCIPAL SE DEBE DECLARAR COMO
C EXTERNAL. FUN Y DEBE SER FUNCION DE UNA VARIABLE
FUN(X),DONDE X ES ARGUMENTO VARIABLE DESDE A HASTA B.
C A - LIMITE INFERIOR DE LA INTEGRAL
C B - LIMITE SUPERIOR DE LA INTEGRAL
C ERR - ES LA PRECISION REQUERIDA
C
C DESCRIPCION DE ARGUMENTOS DE SALIDA:
C ----------------------------------------------------------------------
C ANS - VALOR ENCONTRADO DE LA INTEGRAL
C ERR - ERROR ABSOLUTO DE ANS
C IERR- CODICO DEL ERROR
C IERR=0 -- CODICO NORMAL
C IERR = - 1 , IERR=1 ERROR EN LA DEFINICION DE LOS EXTREMOS
C DEL INTERVALO. A ANS SE ASIGNA EL VALOR CERO.
C IERR=2, ES PROBABLE QUE LA PRECISION DESEADA NO SE ALCANCE
C
DIMENSION AA(40),HH(40),LR(40),VL(40),F4(40),F5(40),S3R(40)
DATA SQ2/1.41421356/,ICALL/0/
DATA NLMN/4/,NLMX/40/,KMX/5000/,KML/9/,NBITS/48/
C
C INICIALIZACION
C
ICALL = 1
ANS = 0.0
IERR = 1
CE = 0.0
IF (A.EQ.B) GO TO 35
LMX = NLMX
LMN = NLMN
IF (B.EQ.0.0) GO TO 4
IF (SIGN(1.0,B)*A.LE.0.0) GO TO 4
C = ABS(1.0-A/B)
IF (C.GT.0.1) GO TO 4
IF (C.LE.0.0) GO TO 35
NIB = 0.5-ALOG(C)/ALOG(2.0)
LMX = MIN0(NLMX , NBITS-NIB-2)
IF (LMX.LT.2) GO TO 32
LMN = MIN0(LMN,LMX)
4 TOL = AMAX1(ABS(ERR),2.0**(5-NBITS))/2.0
IF (ERR.EQ.0.0) TOL = 0.5E-6
EPS = TOL
HH(1) = (B-A)*0.25
AA(1) = A
LR(1) = 1
X = A
F1 = FUN(X)
F3 = FUN(0.5*(A+B))
X = B
F5(1) = FUN(X)
K = 3
8
L = 1
AREA = 0.0
S3 = 0.0
EF = 8.0/15.0
C
C CALCULAR VALORES DE LA INTEGRAL Y EL ERROR
5 F2 = FUN(AA(L)+HH(L))
F4(L) = FUN(AA(L)+3.0*HH(L))
K = K+2
S3L = HH(L)*(F1+F3+4.0*F2)/3.0
S3R(L) = HH(L)*(F3+F5(L)+4.0*F4(L))/3.0
AREA = AREA+(ABS(S3L)+ABS(S3R(L))-ABS(S3))
IF (L.LT.LMN) GO TO 11
S5 = S3L+S3R(L)
EE = ABS(S5-S3)*EF
AE = AMAX1(EPS*AREA,TOL*ABS(S5))
IF (EE-AE) 7,7,10
6 CE = CE+(S3-S5)
GO TO 8
7 CE = CE+(S3-S5)/15.0
8 IF (LR(L)) 15,15,20
C
C CONSIDERAR LA PARTE IZQUIERDA DEL SIGUIENTE NIVEL DEL
C ARBOL RECURSIVO
10 IF (K.GT.KMX) LMX = KML
IF (L.GE.LMX) GO TO 6
11 L = L+1
EPS = EPS*0.5
IF (L.LE.7) EF = EF/SQ2
HH(L) = HH(L-1)*0.5
LR(L) = -1
AA(L) = AA(L-1)
S3 = S3L
F5(L) = F3
F3 = F2
GO TO 5
C
C CONSIDERAR LA PARTE DERECHA DEL SIGUIENTE NIVEL DEL
C ARBOL RECURSIVO
C
15 VL(L) = S5+(S5-S3)/15.0
16 S3 = S3R(L-1)
LR(L) = 1
AA(L) = AA(L)+4.0*HH(L)
F1 = F5(L)
F3 = F4(L-1)
F5(L) = F5(L-1)
GO TO 5
C
C REGRESAR AL NIVEL SUPERIOR DEL PROCESO RECURSIVO
20 VR = S5+(S5-S3)/15.0
22 IF (L.LE.1) GO TO 30
IF (L.LE.7) EF = EF*SQ2
EPS = EPS*2.0
9
L = L-1
IF (LR(L)) 24,24,26
24 VL(L) = VL(L+1)+VR
GO TO 16
26 VR = VL(L+1)+VR
GO TO 22
C
C SALIDA DE DATOS
30 ANS = VR
IF (ABS(CE).LE.2.0*TOL*AREA) GO TO 35
IERR = 2
WRITE(*,*) ‘ ANS ES PROBABLE NO TIENE PRECISION SUFICIENTE’
GO TO 35
32 IERR =-1
WRITE(*,*) ‘EN QNC3 , A Y B ESTAN DEMASIADO CERCA’
35 ICALL = 0
IF (ERR.LT.0.0) ERR = CE
RETURN
END
2.5. Programa QNC7
$debug
implicit real*8 (a-h,o-z)
external func
a=0.0d0
b=1.0d0
err=1.0d-20
call qnc7(FUNC,A,B,ERR,ANS,IERR)
exact=4.0d0*datan(1.0d0)
Write(*,*) ans
write(*,*) exact
read(*,*)
stop
end
c
function func(x)
implicit real*8 (a-h,o-z)
func=4.0*dsqrt(1.0d0-x*x)
return
end
SUBROUTINE QNC7 (FUN,A,B,ERR,ANS,IERR)
C PROGRAMA PARA CALCULAR INTEGRALES USANDO ALGORITMOS
C AUTOADAPTABLES, CON FORMULAS DE CUADRATURAS DE NEWTON -
C COTES CON SIETE NUDOS. SE UTILIZA EL PROCEDIMIENTO RECURSIVO
C DE BISECCION DE LOS INTERVALOS PARA CONTROLAR
C AUTOMATICAMENTE LA PRECISION DESEADA.
C
C DESCRIPCION DE ARGUMENTOS DE ENTRADA:
C -----------------------------------------------------------------------------
C FUN - LA FUNCION A INTEGRA DEBE SER DEFINIDA POR EL USUARIO
C Y EN EL PROGRAMA PRINCIPAL SE DEBE DECLARAR COMO
10
C EXTERNAL. FUN DEBE SER FUNCION DE UNA VARIABLE
C FUN(X),
C DONDE X ES ARGUMENTO QUE VARIA DESDE A HASTA B
C A - LIMITE INFERIOR DE LA INTEGRAL
C B - LIMITE SUPERIOR DE LA INTEGRAL
C ERR - ES LA PRECISION REQUERIDA
C
C DESCRIPCION DE ARGUMENTOS DE SALIDA:
C -----------------------------------------------------------------------------
C ANS - VALOR ENCONTRADO DE LA INTEGRAL
C IERR - ERROR ABSOLUTO DE ANS
C IERR- CODICO DEL ERROR
C IERR=0 -- CODICO NORMAL
C IERR = - 1 , IERR=1 ERROR EN LA DEFINICION DE LOS EXTREMOS
C DEL INTERVALO. A ANS SE LE ASIGNA EL VALOR CERO.
C IERR=2, ES PROBABLE QUE LA PRECISION REQUERIDA NO SE ALCANCE
C
IMPLICIT REAL*8 (A-H,O-Z)
DIMENSION AA(40),HH(40),LR(40),VL(40),Q7R(40),F(13)
DIMENSION F1(40),F2(40),F3(40),F4(40),F5(40),F6(40),F7(40)
DATA SQ2/1.41421356/,ICALL/0/
DATA NLMN/2/,NLMX/40/,KMX/5000/,KML/7/,NBITS/48/
C
C INICIALIZACION
C
ICALL = 1
W1 = 41.0/140.0
W2 =216.0/140.0
W3 = 27.0/140.0
W4 =272.0/140.0
ANS = 0.0
IERR = 1
CE = 0.0
IF (A.EQ.B) GO TO 35
LMX = NLMX
LMN = NLMN
IF (B.EQ.0.0) GO TO 3
IF (SIGN(1.0,B)*A.LE.0.0) GO TO 3
C = ABS(1.0-A/B)
IF (C.GT.0.1) GO TO 3
IF (C.LE.0.0) GO TO 35
NIB = 0.5-ALOG(C)/ALOG(2.0)
LMX = MIN0(NLMX , NBITS-NIB-4)
IF (LMX.LT.2) GO TO 32
LMN = MIN0(LMN,LMX)
3 TOL = AMAX1(ABS(ERR),2.0**(5-NBITS))/2.0
IF (ERR.EQ.0.0) TOL = 0.5E-6
EPS = TOL
HH(1) = (B-A)/12.0
AA(1) = A
LR(1) = 1
DO 4 I=1,13,2
4 F(I) = FUN(A+FLOAT(I-1)*HH(1))
K = 7
11
L = 1
AREA = 0.0
Q7 = 0.0
EF = 128.0/255.0
C
C CALCULAR LOS VALORES DE LA INTEGRAL Y DE ERROR
5 DO 6 I=2,12,2
6 F(I) = FUN(AA(L)+FLOAT(I-1)*HH(L))
K = K+6
Q7L = HH(L)*( ( W1*(F(1)+F(7)) + W2*(F(2)+F(6)) )
1 + ( W3*(F(3)+F(5)) + W4*F(4) ) )
Q7R(L) = HH(L)*( ( W1*(F(7)+F(13)) + W2*(F(8)+F(12)) )
1 + ( W3*(F(9)+F(11)) + W4*F(10) ) )
AREA = AREA + (ABS(Q7L)+ABS(Q7R(L))-ABS(Q7))
IF (L.LT.LMN) GO TO 11
Q13 = Q7L+Q7R(L)
EE = ABS(Q7-Q13)*EF
AE = AMAX1(EPS*AREA,TOL*ABS(Q13))
IF (EE-AE) 8,8,10
7 CE = CE+(Q7-Q13)
GO TO 9
8 CE = CE+(Q7-Q13)/255.0
9 IF (LR(L)) 15,15,20
C
C CONSIDERAR EL SIGUIENTE NIVEL DEL ARBOL RECURSIVO
10 IF (K.GT.KMX) LMX = KML
IF (L.GE.LMX) GO TO 7
11 L = L+1
EPS = EPS*0.5
IF (L.LE.15) EF = EF/SQ2
HH(L) = HH(L-1)*0.5
LR(L) = -1
AA(L) = AA(L-1)
Q7 = Q7L
F1(L) = F(7)
F2(L) = F(8)
F3(L) = F(9)
F4(L) = F(10)
F5(L) = F(11)
F6(L) = F(12)
F7(L) = F(13)
F(13) = F(7)
F(11) = F(6)
F(9) = F(5)
F(7) = F(4)
F(5) = F(3)
F(3) = F(2)
GO TO 5
C
C PROCESAR LA PARTE IZQUIERDA DEL SIGUIENTE NIVEL DEL ARBOL
C RECURSIVO
15 VL(L) = Q13
16 Q7 = Q7R(L-1)
LR(L) = 1
12
AA(L) = AA(L)+12.0*HH(L)
F(1) = F1(L)
F(3) = F2(L)
F(5) = F3(L)
F(7) = F4(L)
F(9) = F5(L)
F(11) = F6(L)
F(13) = F7(L)
GO TO 5
C
C
C VOLVER AL NIVEL ANTERIOR DEL ARBOL RECURSIVO
C
C
20 VR = Q13
22 IF (L.LE.1) GO TO 30
IF (L.LE.15) EF = EF*SQ2
EPS = EPS*2.0
L = L-1
IF (LR(L))24,24,26
24 VL(L) = VL(L+1)+VR
GO TO 16
26 VR = VL(L+1)+VR
GO TO 22
C
C EXIT
C
30 ANS = VR
IF (ABS(CE).LE.2.0*TOL*AREA) GO TO 35
IERR = 2
WRITE(*,*) ‘EN QNC7 , ES PROBABLE EL RESULTADO NO TIENE ‘
WRITE(*,*) ‘ LA PRECISION REQUERIDA
GO TO 35
32 IERR =-1
WRITE(*,*) ‘ LOS EXTREMOS A Y B ESTAN DEMASIADO CERCA’
35 ICALL = 0
IF (ERR.LT.0.0) ERR = CE
RETURN
END
2.6. Programa QNC9
$debug
c Programa Prueba para QNC9
c
External Fun
Real*8 a,b,Abserr,Relerr,Result,Errest,Flag
Integer Nofun
a=0.0d0
b=2.0d0
Relerr=1.0d-10
Abserr=0.0d0
Call Qnc9(Fun,a,b,Abserr,Relerr,Result,Errest,Nofun,Flag)
13
Write(*,1) Result,Errest
If (Flag.ne.0.0d0) Write(*,2) Flag
1 Format(2x,'Result= ',F15.10,' Errest= ',D10.2)
2 Format('Cuidado! El resultado puede tener error Flag= ',F6.2)
Stop
End
c
c Función bajo el símbolo de integral
c
function fun(x)
implicit real*8 (a-h,o-z)
func=4.0*dsqrt(1.0d0-x*x)
return
end
c
Subroutine Qnc9(Fun,a,b,Abserr,Relerr,Result,Errest,Nofun,Flag)
c
Real*8 Fun,a,b,abserr,relerr,result,errest,flag
Integer nofun
c
c Buscar integral de fun(x) desde a hasta b
c con precisión definida por el usuario
c Programa auto-adaptable, fundamentado
c en la fórmula de Newton - Cotes del orden 8
c
c INFORMACION DE LA ENTRADA:
c
c FUN - nombre de la función fun(x) bajo
c el símbolo de la integral, la cual debe ser definida
c en un subprograma del usuario
c a,b - límites de integración : inferior y superior
c relerr - error relativo aceptable (no negativo)
c abserr - error absoluto aceptable (no negativo)
c
c INFORMACION DE SALIDA:
c
c result - valor aproximado de la integral
c errest - estimación del valor real del error
c nofun - número de accesos al cálculo de la
c función fun(x) para obtener result
c flag - parámetro de confianza.. Si flag es igual
c a 0, el result satisface una de las
c condiciones: abserr o relerr. Si flag
c =XXX.YYY, entonces XXX - es el número de
c intervalos en los cuales el proceso no
c se converge, a 0.YYY -es la parte del
c intervalo inicial, no pasado en el momento
c cuando NOFUN se acerco a su valor limite
c
Real*8 W0,W1,W2,W3,W4,Area,X0,F0,Stone,Step,
$ Cor11,Temp
Real*8 Qprev,Qnow,Qdiff,Qleft,Esterr,Tolerr
Real*8 Qright(31),F(16),X(16),Fsave(8,30),
$ Xsave(8,30)
14
Integer Levmin,Levmax,Levout,Nomax,Nofin,
$ Lev,Nim,I,J
c
c PRIMERA ETAPA
c Definición de los valores iniciales de las
c variables de integración y las constantes
c independientes del intervalo de integración .
c
Levmin=1
Levmax=30
Levout=6
Nomax=5000
Nofin=Nomax-8*(Levmax-Levout+2**(Levout+1))
c
c Si Nofun se aumenta hasta Nofin, entonces Alerta!!!
c
W0=3956.0d0/14175.0d0
W1=23552.0d0/14175.0d0
W2=-3712.0d0/14175.0d0
W3=41984.0d0/14175.0d0
W4=-18160.0d0/14175.0d0
c
c Asignar valor de cero a las variables sumas
Flag=0.0d0
Result=0.0d0
Cor11=0.0d0
Errest=0.0d0
Area=0.0d0
Nofun=0
If (a.eq.b) Return
c
c SEGUNA ETAPA
c Asignar valores iniciales a las variables
c que dependen del intervalo, de acuerdo al
c primer intervalo
c
Lev=0
Nim=1
X0=a
X(16)=b
Qprev=0.0d0
F0=Fun(x0)
Stone=(b-a)/16.0d0
X(8)=(X0+X(16))/2.0d0
X(4)=(X0+X(8))/2.0d0
X(12)=(X(8)+X(16))/2.0d0
X(2)=(X0+X(4))/2.0d0
X(6)=(X(8)+X(4))/2.0d0
X(14)=(X(12)+X(16))/2.0d0
X(10)=(X(8)+X(12))/2.0d0
Do j=2,16,2
F(j)=Fun(X(j))
End do
15
Nofun=9
c
c TERCERA ETAPA
c Principales cálculos . Se utilizan valores, Qprev,
c X0,X2,X4,...,X16
c y F0,F2,F4,...,F16 para calcular X1,X3,X5,...,X15 y F1,F3,
c F5,...,F15,Qleft.Qright,Qnow,Qdiff,Area
c
30 X(1)=(X0+X(2))/2.0d0
F(1)=Fun(X(1))
Do j=3,15,2
X(j)=(X(j-1)+X(j+1))/2.0d0
F(j)=Fun(X(j))
End do
Nofun=Nofun+8
Step=(X(16)-X0)/16.0d0
Qleft=(W0*(F0+F(8))+W1*(F(1)+F(7))+W2*(F(2)+F(6))
$ +W3*(F(3)+F(5))+W4*F(4))*Step
Qright(Lev+1)=(W0*(F(8)+F(16))+W1*(F(9)+F(15))+
$ W2*(F(10)+F(14))+W3*(F(11)+F(13))+
$ W4*F(12))*Step
Qnow=Qleft+Qright(Lev+1)
Qdiff=Qnow-Qprev
Area=Area+Qdiff
c
c CUARTA ETAPA
c Verificar la convergencia del intervalo
c
Esterr=dabs(Qdiff)/1023.0d0
Tolerr=Relerr*Dabs(Area)
If(Abserr.gt.Tolerr) Tolerr=Abserr
Tolerr=Tolerr*Step/Stone
c Tolerr=Damax1(Abserr,Relerr*Dabs(Area))*
c $ (Step/Stone)
If(Lev.lt.Levmin) go to 50
If(Lev.ge.Levmax) go to 62
If(Nofun.gt.Nofin) go to 60
If(Esterr.le.Tolerr) go to 70
c
c QUINTA ETAPA
c Si no hay convergencia
c Definir el siguiente intervalo
c
50 Nim=2*Nim
Lev=Lev+1
c
c Almacenar los elementos de la parte derecha
c del intervalo, para usarlos posteriormente
c
Do i=1,8
Fsave(i,Lev)=F(i+8)
Xsave(i,Lev)=X(i+8)
End do
c
16
c Almacenar los elementos de la parte izquierda
c del intervalo, para usarlos posteriormente.
Qprev=Qleft
Do i=1,8
j=-i
F(2*j+18)=F(j+9)
X(2*j+18)=X(j+9)
End do
Go to 30
c
c SEXTA ETAPA (Alerta)
c
c El número de cálculos de la función
c se acercó al número crítico y puede
c superar el límite establecido
c
60 Nofin = 2*Nofin
Levmax=Levout
Flag=Flag+(b-X0)/(b-a)
Go to 70
c
c Cuando el número de bisecciones
c es igual a Levmax
c
62 Flag=Flag+1.0d0
c
c SEPTIMA ETAPA
c proceso para cuando el intervalo converge
c Adicionar nuevos resultados a las sumas
c variables
c
70 Result=Result+Qnow
Errest=Errest+Esterr
Cor11=Cor11+Qdiff/1023.0d0
c Write(*,*) result
c
c Establecer el siguiente intervalo
c
72 If(Nim.eq.2*(Nim/2)) go to 75
Nim=Nim/2
Lev=Lev-1
Go to 72
75 Nim=Nim+1
If(Lev.le.0) go to 80
c
c Organizar los elementos
c para el intervalo siguiente
c
Qprev=Qright(Lev)
X0=X(16)
F0=F(16)
Do i=1,8
F(2*i)=Fsave(i,Lev)
X(2*i)=Xsave(i,Lev)
17
End do
Go to 30
c
c OCTAVA ETAPA
c Operaciones finales y salida
c de resultados
c
80 Result=Result+Cor11
c
c El valor del Errest debe ser mayor
c que el error por redondeo
c
If (Errest.eq.0.0d0) Return
82 Temp=Dabs(Result)+Errest
If(Temp.ne.Dabs(Result)) Return
Errest=2.0d0*Errest
Go to 82
End
2.7. Programa GAUS8
$debug
implicit real*8 (a-h,o-z)
external func
a=0.0d0
b=1.0d0
err=1.0d-15
call GAUS8(FUNC,A,B,ERR,ANS,IERR)
exact=4.0d0*datan(1.0d0)
Write(*,*) ans
write(*,*) exact
read(*,*)
stop
end
c
function func(x)
implicit real*8 (a-h,o-z)
func=4.0*dsqrt(1.0-x*x)
return
end
c
SUBROUTINE GAUS8 (FUN,A,B,ERR,ANS,IERR)
c
C PROGRAMA DE CALCULO DE LA INTEGRAL USANDO UN ALGORITMO AUTOADAPTABLE
C PARA FORMULAS DE DE GAUSS - LEGENDRE CON OCHO NUDOS .
C SE UTILIZA EL PROCEDIMIENTO RECURSIVO DE BISECCION DE LOS INTERVALOS PARA
C CONTROL AUTOMATICO DE LA PRECISION REQUERIDA.
C
C
C DESCRIPCION DE ARGUMENTOS DE ENTRADA:
C -----------------------------------------------------------------------------
C FUN - FUNCION SUBINTEGRAL. DEBE SR DEFINIDA POR EL USUARIO .
C EN PROGRAMA PRINCIPAL DEBE SER DECLARADA COMO EXTERNAL
18
C FUN DEBE SER FUNCION DE UNA VARIABLE FUN(X), DONDE X ES
C ARGUMENTO QUE SE VARIA DESDE A HASTA B.
C A - LIMITE INFERIOR DE LA INTEGRAL
C B - LIMITE SUPERIOR DE LA INTEGRAL
C ERR - ES LA PRECISION REQUERIDA
C
C DESCRIPCION DE ARGUMENTOS DE SALIDA:
C -----------------------------------------------------------------------------
C ANS - VALOR DE LA INTEGRAL ENCONTRADO
C ERR - ERROR ABSOLUTO DE ANS
C IERR- CODICO DEL ERROR
C IERR=0 -- CODICO NORMAL
C IERR = - 1 , IERR=1 ERROR EN LA DEFINICION DE LOS EXTREMOS
C DEL INTERVALO. A ANS SE ASIGNA EL VALOR CERO.
C IERR=2 ES PROBABLE QUE LA PRECISION REQUERIDA NO SE ALCANZO
C
implicit real*8 (a-h,o-z)
DIMENSION AA(30),HH(30),LR(30),VL(30),GR(30)
DATA X1,X2,X3,X4/0.18343 46424 95650 , 0.52553 24099 16329 ,
1 0.79666 64774 13627 , 0.96028 98564 97536 /
DATA W1,W2,W3,W4/0.36268 37833 78362 , 0.31370 66458 77887 ,
1 0.22238 10344 53374 , 0.10122 85362 90376 /
DATA SQ2/1.41421356d0/,ICALL/0/
DATA NLMN/1/,NLMX/30/,KMX/5000/,KML/6/,NBITS/48/
G8(X,H) = H*( (W1*(FUN(X-X1*H)+FUN(X+X1*H))
1 +W2*(FUN(X-X2*H)+FUN(X+X2*H)))
2 +(W3*(FUN(X-X3*H)+FUN(X+X3*H))
3 +W4*(FUN(X-X4*H)+FUN(X+X4*H))) )
C
C INICIALIZACION
ICALL = 1
ANS = 0.0d0
IERR = 1
CE = 0.0d0
IF (A.EQ.B) GO TO 35
LMX = NLMX
LMN = NLMN
IF (B.EQ.0.0) GO TO 4
IF (DSIGN(1.0D0,B)*A.LE.0.0d0) GO TO 4
C = ABS(1.0d0-A/B)
IF (C.GT.0.1d0) GO TO 4
IF (C.LE.0.0d0) GO TO 35
NIB = 0.5d0-dLOG(C)/dLOG(2.0d0)
LMX = MIN0(NLMX , NBITS-NIB-7)
IF (LMX.LT.1) GO TO 32
LMN = MIN0(LMN,LMX)
4 TOL = AMAX1(ABS(ERR),2.0d0**(5-NBITS))/2.0d0
IF (ERR.EQ.0.0d0) TOL = 0.5d-6
EPS = TOL
HH(1) = (B-A)/4.0d0
AA(1) = A
LR(1) = 1
L = 1
19
EST = G8(AA(L)+2.0d0*HH(L),2.0d0*HH(L))
K = 8
AREA = ABS(EST)
EF = 0.5d0
MXL = 0
C
C CALCULAR LAS SUMAS Y ESTIMAR EL ERROR.
C
5 GL = G8(AA(L)+HH(L),HH(L))
GR(L) = G8(AA(L)+3.0d0*HH(L),HH(L))
K = K+16
AREA = AREA+(ABS(GL)+ABS(GR(L))-ABS(EST))
C IF (L.LT.LMN) GO TO 11
GLR = GL+GR(L)
EE = ABS(EST-GLR)*EF
AE = AMAX1(EPS*AREA,TOL*ABS(GLR))
IF (EE-AE) 8,8,10
7 MXL = 1
8 CE = CE + (EST-GLR)
IF (LR(L)) 15,15,20
C
C CONSIDERAR LA PARTE IZQUIERDA DE ESTE NIVEL
10 IF (K.GT.KMX) LMX = KML
IF (L.GE.LMX) GO TO 7
11 L = L+1
EPS = EPS*0.5d0
EF = EF/SQ2
HH(L) = HH(L-1)*0.5d0
LR(L) = -1
AA(L) = AA(L-1)
EST = GL
GO TO 5
C
C CONSIDERAR LA PARTE DERECHA DE ESTE NIVEL
C
15 VL(L) = GLR
16 EST = GR(L-1)
LR(L) = 1
AA(L) = AA(L)+4.0d0*HH(L)
GO TO 5
C VOLVER AL NIVEL ANTERIOR
C
20 VR = GLR
22 IF (L.LE.1) GO TO 30
L = L-1
EPS = EPS*2.0d0
EF = EF*SQ2
IF (LR(L)) 24,24,26
24 VL(L) = VL(L+1)+VR
GO TO 16
26 VR = VL(L+1)+VR
GO TO 22
C SALIDA
30 ANS = VR
20
IF ((MXL.EQ.0).OR.(ABS(CE).LE.2.0*TOL*AREA)) GO TO 35
IERR = 2
WRITE(*,*) ‘ ES POSIBLE QUE EL RESULTADO ’
WRITE(*,*) ‘ NO TIENE LA PRECISION REQUERIDA’
GO TO 35
32 IERR =-1
WRITE(*,*) ‘ HAY ERROR EN LA DEFINICION DE LOS EXTREMOS DEL INTERVALO’
35 ICALL = 0
IF (ERR.LT.0.0) ERR = CE
RETURN
END
III. FORMULAS DE CUADRATURAS EN D DIMENSIONES
3.1 Reducción de una Integral Múltiple a otra Reiterada. Programa REITER
Consideremos un método para reducir la integración de funciones de varias variables al cálculo de integración sucesiva de
funciones de una sola variable. Ilustraremos el método con una integral bidimensional, en un conjunto G (figura 3.1):
G = {x,y} : a x b , (x) y (x)}
donde (x) (x), dentro del segmento [a,b]
G
ba
y
x
Figura 3.1 Conjunto de Integración
( )x
( )x
Si la función f(x,y), es integrable para todo x [a,b], entonces la función
F x f x y dyx
x
( ) ( , )( )
( )
(3.1)
es integrable, en el segmento [a,b] y la integral doble se reduce a una integral reiterada,
I f x y dxdy dx f x y dy F x dxa
b
a
b
x
x
G
( , ) ( , ) ( )( )
( )
( )
(3.2)
Las fórmulas (3.1) y (3.2) permiten elaborar un algoritmo simple, llamado REITER, texto del cual, se detalla a continuación:
REITER
c! Complejo de programas para calcular integrales dobles.
21
c! Función func(x,y) dentro del conjunto :
c! G {(x,y): a<x<b; front1(x)<y<front2(x)}
c! reducción de una integral doble a otra reiterada. El cálculo se realiza
c! en dos etapas:
c! a) se construye la función FunDbl(x) - la integral
c! de la función f(x,y) respecto y, para
c! frot1(x) < y < front2(x)
c! b) se calcula la integral para la función FunDbl(x) para
c! a < x < b
c! En cada etapa se utiliza el programa de integración
c! autoadaptable QNC9, pero en la primera etapa su modificación
c! QNC8PAR, en el cual la segunda variable x se considera como
c! un parámetro.
c! Para llamar el programa hay que escribir la siguiente instrucción
c! Call Dblint(func,a,b,front1,front2,Res,Err,Nofun)
c! El usuario debe en el programa principal declarar
c1 External func,front1,front2
c! y definir los extremos a,b. Además el usuario debe confeccionar
c! tres subprogramas:
c! Real*8 Function Func(x,y)
c! Real*8 Function Front1(x)
c! Real*8 Function Front2(x)
c! El programa después de ejecución define la estimación del valor
c! de la integral Res, definida con precisión máxima posible,
c! el valor de la precisión alcanzada Err, y el número accesos Nofun
c! en el cálculo de la función Func(x,y)
c
Subroutine Dblint(func,a,b,front1,front2,Res,Err,nofun)
c
External Func,FunDbl,front1,front2
Real*8 Func,Fundbl,a,b,front1,front2,abserr,relerr,res,
+ err,flag
Integer nofun
Common /NNN/ nofunc
c
c El programa autoadaptable está basado
c en la formula de Newton - Cotes de orden 8
c
c INFORMACION DE ENTRADA:
c
c FUNC - nombre de la función func(x) bajo
c el signo de la integral, la cual debe ser definida
c en subprograma del usuario
c a,b,c,d - límites inferior y superior del intervalo
c de integración
c
c INFORMACION DE SALIDA:
c
c res - valor aproximado de la integral
c err - estimación del valor real del error
c
c Presiciones en el subprograma
c
22
c relerr - error relativo aceptable (nonegativo)
c abserr - error absoluto aceptable (nonegativo)
Relerr=1.0d-8
Abserr=0.0d0
Call Qnc9(FunDbl,a,b,Abserr,Relerr,Res,
$ Err,Nofun1,Flag)
nofun=nofunc
c Write(*,1) Res,Err
c If (Flag.ne.0.0d0) Write(*,2) Flag
1 Format('Result= ',F15.10,'Errest= ',D10.2)
2 Format( 'Cuidado .. Resultado Puede Ser Equivocado Flag= ',F6.2)
Return
End
c
c Función bajo el signo de la segunda integral repetida
c
Real*8 Function FunDbl(x)
External Func,front1,front2
Real*8 c,d,func,front1,front2,Abserr,Relerr,Res,Err,Flag
Integer Nofun
Real*8 x
Common /NNN/ Nofunc
c write(*,*) 'x= ',x
Relerr=1.0d-12
Abserr=0.0d0
c=front1(x)
d=front2(x)
Call Qnc9Par(Func,c,d,Abserr,Relerr,Res,Err,Flag,x)
c Write(*,*) x,Res,Err
c If (Flag.ne.0.0d0) Write(*,2) Flag
1 Format('Result= ',F15.10,'Errest= ',D10.2)
2 Format(
$ 'Cuidado.. Resultado Puede Ser Equivocado Flag= ',F6.2)
FunDbl= Res
Return
End
c
Subroutine Qnc9Par(fun,a,b,abserr,relerr,result,errest,flag,arg)
implicit double precision (a-h,o-z)
c
c
c Real*8 Fun,a,b,abserr,relerr,result,errest,flag
Integer nofun
c
c Encontrar integral para fun(arg,x) para x desde a hasta b
c con la precisión definida por el usuario
c Programa autoadaptable basado
c en la fórmula de Newton - Cotes de orden 8
c
Real*8 W0,W1,W2,W3,W4,Area,X0,F0,Stone,Step,
$ Cor11,Temp
Real*8 Qprev,Qnow,Qdiff,Qleft,Esterr,Tolerr
Real*8 Qright(31),F(16),X(16),Fsave(8,30),
$ Xsave(8,30),arg
23
Integer Levmin,Levmax,Levout,Nomax,Nofin,
$ Lev,Nim,I,J
External Fun
common /NNN /nofunc
data Nofunc/0/
c
c ETAPA NUMERO 1
c
c Definicion de los valores iniciales de las
c variables, no dependientes del intervalo de
c integracion y de las constantes
c
Levmin=1
Levmax=30
Levout=6
Nomax=5000
Nofin=Nomax-8*(Levmax-Levout+2**(Levout+1))
c
c Si Nofun se aumenta hasta Nofin, entonses Alerta!!!
c
W0=3956.0d0/14175.0d0
W1=23552.0d0/14175.0d0
W2=-3712.0d0/14175.0d0
W3=41984.0d0/14175.0d0
W4=-18160.0d0/14175.0d0
c Asignar el valor zero a las sumas variables
c
Flag=0.0d0
Result=0.0d0
Cor11=0.0d0
Errest=0.0d0
Area=0.0d0
Nofun=0
If (a.eq.b) Return
c
c ETAPA NUMERO 2
c
c Asignar los valores iniciales a las variables
c que dependen del intervalo, en corcondancia
c con el primer intervalo
c
Lev=0
Nim=1
X0=a
X(16)=b
Qprev=0.0d0
F0=Fun(arg,x0)
Stone=(b-a)/16.0d0
X(8)=(X0+X(16))/2.0d0
X(4)=(X0+X(8))/2.0d0
X(12)=(X(8)+X(16))/2.0d0
X(2)=(X0+X(4))/2.0d0
X(6)=(X(8)+X(4))/2.0d0
X(14)=(X(12)+X(16))/2.0d0
24
X(10)=(X(8)+X(12))/2.0d0
Do k=1,8
j=k*2
c write(*,*) k,j,x(j)
F(j)=Fun(arg,X(j))
c write(*,*) k,j,f(j)
End do
Nofun=9
c
c ETAPA NUMERO 3
c
c Cálculos principales. Se utilizan valores,Qprev,
c X0,X2,X4,...,X16
c y F0,F2,F4,...,F16 para calcular X1,X3,X5,...,X15 y F1,F3,
c F5,...,F15,Qleft.Qright,Qnow,Qdiff,Area
c
30 X(1)=(X0+X(2))/2.0d0
F(1)=Fun(arg,X(1))
Do j=3,15,2
X(j)=(X(j-1)+X(j+1))/2.0d0
F(j)=Fun(arg,X(j))
End do
Nofun=Nofun+8
Step=(X(16)-X0)/16.0d0
Qleft=(W0*(F0+F(8))+W1*(F(1)+F(7))+W2*(F(2)+F(6))
$ +W3*(F(3)+F(5))+W4*F(4))*Step
Qright(Lev+1)=(W0*(F(8)+F(16))+W1*(F(9)+F(15))+
$ W2*(F(10)+F(14))+W3*(F(11)+F(13))+
$ W4*F(12))*Step
Qnow=Qleft+Qright(Lev+1)
Qdiff=Qnow-Qprev
Area=Area+Qdiff
c
c ETAPA NUMERO 4
c
c Chequeo de convergencia para el intervalo
c
Esterr=dabs(Qdiff)/1023.0d0
Tolerr=Relerr*Dabs(Area)
If(Abserr.gt.Tolerr) Tolerr=Abserr
Tolerr=Tolerr*Step/Stone
c Tolerr=Damax1(Abserr,Relerr*Dabs(Area))*
c $ (Step/Stone)
If(Lev.lt.Levmin) go to 50
If(Lev.ge.Levmax) go to 62
If(Nofun.gt.Nofin) go to 60
If(Esterr.le.Tolerr) go to 70
c
c ETAPA NUMERO 5
c
c No hay convergencia
c Definir el intervalo siguiente
c
50 Nim=2*Nim
25
Lev=Lev+1
c
c Almacenar los elementos de la parte derecha
c del intervalo para usarlos en adelante
c
Do i=1,8
Fsave(i,Lev)=F(i+8)
Xsave(i,Lev)=X(i+8)
End do
c
c Organizar los elementos de la parte izquierda
c del intervalo para usarlos
c
Qprev=Qleft
Do i=1,8
j=-i
F(2*j+18)=F(j+9)
X(2*j+18)=X(j+9)
End do
Go to 30
c
c ETAPA NUMERO 6 (Alerta)
c
c Número de cálculos de la función
c se acercó al número crítico y puede
c superar el límite establecido
c
60 Nofin = 2*Nofin
Levmax=Levout
Flag=Flag+(b-X0)/(b-a)
Go to 70
c
c Número de bisecciones
c es igual a Levmax
c
62 Flag=Flag+1.0d0
c
c ETAPA NUMERO 7
c
c El proceso para el intervalo converge
c Adicionar nuevos resultados a las sumas
c variables
c
70 Result=Result+Qnow
Errest=Errest+Esterr
Cor11=Cor11+Qdiff/1023.0d0
c Establecer el intervalo siguiente
c
72 If(Nim.eq.2*(Nim/2)) go to 75
Nim=Nim/2
Lev=Lev-1
Go to 72
75 Nim=Nim+1
If(Lev.le.0) go to 80
26
c
c Organizar los elementos
c para el intervalo siguiente
c
Qprev=Qright(Lev)
X0=X(16)
F0=F(16)
Do i=1,8
F(2*i)=Fsave(i,Lev)
X(2*i)=Xsave(i,Lev)
End do
Go to 30
c
c ETAPA NUMERO 8
c
c Operaciones finales y salida
c de los resultados
c
80 Result=Result+Cor11
Nofunc=nofunc+nofun
c
c El valor del Errest debe ser mayor
c del error por redondeo
c
If (Errest.eq.0.0d0) Return
82 Temp=Dabs(Result)+Errest
If(Temp.ne.Dabs(Result)) Return
Errest=2.0d0*Errest
Go to 82
End
Este programa en el cálculo de integrales unidimensionales, usa el programa autoadaptable QNC9, con fórmulas de
cuadraturas, de orden 9. Nosotros para verificar la eficiencia de los algoritmos, confeccionamos otros dos programas, que
utilizan los algoritmos: QNC3 y QNC7 y realizamos varias simulaciones. Una de ellas es la integral,
e dxdy dx e dy ex y x y
x
x
x y
( ) ( ) ( )2 2 2 2
2
2
2 2
1
1
1
1
1
1
, (3.3)
cuyos resultados se analizan en la tabla 3.1.
Tabla 3.1
Alfa Integral Nofun
QNC7 QNC9 EXACTO QNC7 QNC9
1.0 1.985865303 1.985865303 1.985865359 18840 18111
4.0 .771013094 .771013086 .771013115 45912 35070
9.0 .349022772 .349022552 .349022782 78696 42557
16.0 .196349518 .196349518 .196349524 123696 60892
25.0 .125663706 .125663705 .125663709 182016 80667
27
Se debe anotar que esta integral, para valores grandes de , es muy difícil de calcular con precisión alta, debido a que adopta
la forma de una función singular, tipo -función. Por eso, la tabla muestra que cuando crece, el número de cálculos y el
tiempo de computación también aumentan muy rápidamente. De esta manera, la tabla muestra la ventaja del programa
QNC9B, comparado con QNC7B: el tiempo de computación para grandes, es aproximadamente dos veces menos.
También se presenta el texto del programa principal, de estos cálculos. Este texto puede servir, como un ejemplo, para
confeccionar programas y funciones necesarias, para manejar el programa REITER.
$debug
c Programa Prueba para REITER
c
Real*8 a,b,Res,Err,func,front1,front2,funDbl,par,rad,resex
c
External Func,FunDbl,front1,front2
common /PPP/ par,rad
c write(*,*) ' Teclee parameter Rounge'
c read(*,*) par1
open(1,file='qnc8.res')
rad=1.0d0
a=-rad
b=rad
pi=4.0d0*datan(1.0d0)
do i=1,5
par=1.0d0*i*i
resex=pi/par*(1.0d0-dexp(-par*rad*rad))
Call Dblint(func,a,b,front1,front2,Res,Err,nofunc)
c
Write(*,*) Res,Nofunc,Err
Write(*,*) resex,par
Write(1,1) par,Res,resex,Nofunc
end do
1 format(2x,f4.1,2f18.10,i10)
close(1)
Read(*,*)
Stop
End
c
c Función bajo el signo de la integral doble
c
Real*8 Function Func(x,y)
Real*8 x,y,x2,y2,r2,par,rad
common /PPP/ par,rad
x2=x*x
y2=y*y
r2=x2+y2
Func=dexp(-par*r2)
Return
End
c
c Definir función de la frontera inferior del conjunto (x,y)
c
Real*8 Function Front1(x)
Real*8 x,rad,par
common /PPP/ par,rad
28
Front1=-dsqrt(rad*rad-x*x)
Return
End
c
c Función de la frontera superior del conjunto (x,y)
c
Real*8 Function Front2(x)
Real*8 x,rad,par
common /PPP/ par,rad
Front2=dsqrt(rad*rad-x*x)
Return
End
3.2 Fórmulas de Cuadraturas de Newton-Cotes en D Dimensiones para un Hiperrectángulo
Las fórmulas de cuadraturas de Newton-Cotes, se generalizan fácilmente, para D dimensiones dentro de un hiperrectángulo:
GD = {xi : a(i) xi b(i) ; i = 1, 2, ..., D} (3.4)
Para deducir estas fórmulas, representamos la integral múltiple en forma de una reiterada:
I f x x x dx dx dx dx dx dx f x x xD D Da
b
D Da D
b D
a
b
GD
... ( , ,..., ) ... ... ( , ,..., )( )
( )
( )
( )
( )
( )
( )
1 2 1 2 11
1
2 1 22
2
(3.5)
y aplicamos sucesivamente las fórmulas de Newton-Cotes, para integrales unidimensionales. De esta manera se obtiene:
I V W fk
n
k
n
k
nD k k k
D
k k k
n
D
D
1 2
1 12
1 2
0
, ,...,
, ,...,
, ,..., , (3.6)
donde, V b i a ii
D
[ ( ) ( )]1
; W Wk k k k
i
D
D i1 2
1
, ,...,
n es el número de subdivisiones y Wk son los coeficientes de Cotes definidos por la fórmula (2.4) y la tabla 2.1.
Para aclarar detalles consideremos, el caso de un rectángulo bidimensional para n = 2 (fórmula de curvaturas de Simpson)
G2 = {(x1, x2) : a1 x1 b1 , a2 x2 b2} (3.7)
representado en la figura 3.1. En este caso, según (3.5)
I f x x dx dx dx f x x dxa
b
a
b
G
2 1 2 1 2 1 1 2 22
2
1
1
2
( , ) ( , )( )
(3.8)
29
1 4 1
4 16 4
1 4 1
0
x2
x1
x b2
2
2
( )
x a2
0
2
( )
x a1
0
1
( ) x b1
2
1
( ) x1
1( )
x2
1( )
Figura 3.1 Nodos y Coeficiente de Cotes, para las Fórmulas
de Curvaturas de Simpson en un Rectángulo Bidimensional (3.7)
Dividamos los intervalos de integración, (a1, b1) y (a2, b2), en dos partes: x a h ii
i1 1
( ) , x a h ii
2 2 2
( ) ,
h b a1 1 1 2 ( ) / , h b a2 2 2 2 ( ) / . Entonces aplicando a la integral interior las fórmulas (2.2), (2.6) y (2.7) y usando
los coeficientes Wk para n = 2 de la tabla 2.7, se obtiene
Ib a
f x x f x x f x xc
ndx
a
b
22 2
1 2
0
1 2
1
1 2
2 11
64
1
1
( )( , ) ( , ) ( , )( ) ( ) ( )
(3.9)
A las tres integrales respecto a la variable x1, en (3.9), se les pueden aplicar de nuevo, aplicar las fórmulas de Simpson.
Finalmente, tenemos
Ib a b a c
n2
1 1 2 2
0 1 2 4364 16
( )( )[ ] (3.10)
Donde 0 , 1 y 2, son sumas de los valores de la función en los vértices, centros de los lados del rectángulo y en el centro,
respectivamente (figura 3.1).
0 = f x x f x x f x x f x x( , ) ( , ) ( , ) ( , )( ) ( ) ( ) ( ) ( ) ( ) ( ) ( )
1
0
2
0
1
0
2
2
1
2
2
0
1
2
2
2
1 = f x x f x x f x x f x x( , ( , ) ( , ) ( , )( ) ( ) ( ) ( ) ( ) ( ) ( ) ( )
1
1
2
0
1
0
2
1
1
2
2
1
1
1
2
2 (3.11)
2 = f x x( , )( ) ( )
1
1
2
1
Los algoritmos autoadaptables para las fórmulas (3.10) y (3.11), se construyen de forma similar al caso unidimensional,
excepto que el proceso recursivo, tiene una estructura de un árbol ternario y no binario, como en el unidimensional. Es decir,
la integral se calcula dos veces. Una aplicando las fórmulas (3.10) y (3.11) en todo el rectángulo y otra vez, como suma de
cuatro integrales en cuatro subconjuntos, formados después del proceso de bisección del rectángulo. Si la diferencia entre
estos dos resultados, satisfacen la condición (2.18), entonces el proceso se detiene. En caso contrario, el procedimiento se
aplica sucesivamente a los cuatro subconjuntos.
Nosotros presentamos el texto del programa MULTIDIM, que realiza el algoritmo autoadaptable para las fórmulas de
cuadraturas. El programa permite encontrar integrales múltiples, dentro de un hiperrectángulo, en un espacio con dimensión
2 D 15. El programa también contiene comentarios explícitos paso a paso.
30
C
SUBROUTINE MULTIDIM(NDIM,A,B,MINPTS,MAXPTS,FUNCTN,EPS,ACC,
$ LENWRK,WRKSTR,FINVAL,IFAIL)
C
C SUBPROGRAMA AUTOADAPTABLE PARA CALCULAR INTEGRAL
C MULTIPLE A TRAVES DE FORMULAS DE CUADRATURAS, DENTRO DE
C UN HIPERRECTANGULO
C
C PARAMETER0S DE ENTRADA:
C ------------------------------
C NDIM - INTEGER, NUMERO DE VARIABLES, ( 1 < NDIM < 16)
C A(I) - REAL*8, LIMITES INFERIORES DE LA INTEGRAL (I=1,2...,NDIM)
C B(I) - REAL*8, LIMITES SUPERIORES DE LA INTEGRAL (I=1,2...,NDIM)
C MINPTS - INTEGER, NUMERO MINIMO PERMITIDO DE CALCULOS DE LA
C FUNCION SUBINTEGRAL.
C DEFINICION DEL TIEMPO MINIMO DE COMPUTACION.
C MAXPTS - INTEGER, NUMERO MAXIMO PERMITDO DE CALCULOS DE
C LA FUNCION SUBINTEGRAL
C . DEFINICION DEL TIEMPO MAXIMO DE COMPUTACION.
C (MAXPTS > MINPTS; MAXPTS > 2*NDIM+2*NDIM**2+2*NDIM+1).
C FUNCTN - FUNCION SUBINTEGRAL, DECLARADA EN PROGRAMA
C PRINCIPAL A TRAVES DE INSTRUCCION EXTERNAL Y DEFINIDA POR EL
C USUARIO COMO REAL*8 FUNCTION FUNCTN(NDIM,Z), DONDE Z(I),
C I=1,2...,NDIM SON NDIM ARGUMENTOS DE LA FUNCION.
C EPS - REAL*8 PRECISION REQUIERRIDA ( EPS > 0)
C LENWRK - INTEGER, DIMENSION DEL ARREGLO AUXILIAR WRKSTR,
C LENWRK > 2*NDIM+4.
C
C PARAMETEROS DE SALIDA:
C ------------------------
C FINVAL - REAL*8, EL VALOR ENCONTRADO DE LA INTEGRAL
C MINPTS - NTEGER,NUMERO DE CALCULOS DE LA FUNCION SUBINTEGRAL
C USADOS EN EL PROCESO PARA CALCULAR LA INTEGRAL
C ACC - REAL*8, PRECISION ALCANZADA EN EL CALCULO DE FINVAL
C IFAIL - IFAIL=0, EL PROCESO DE CALCULO FUE NORMAL
C IFAIL=1, SI NDIM.LT.2, NDIM.GT.15, MINPTS.GT.MAXPTS,
C MAXPTS.LT.2**NDIM+2*NDIM*(NDIM+1)+1, EPS.LE.0
C OR LENWRK.LT.2*NDIM+4.
C IFAIL=2, SI EL VALOR MAXPTS SE TOMO DEMASIADO PEQUEÑO
C PARA ALCANZAR LA PRECISION REQUERIDA EPS.
C IFAIL=3, SI LENWRK FUE USADO DEMASIADO PEQUEÑO PARA
C MAXPTS VALORES DE LA FUNCION SUBINTEGRAL CALCULADOS.
C PARAMETRO AUXILIAR:
C ------------------------
C WRKSTR(I) - REAL*8, ARREGLO DE DIMENSION LENWRK, I=1,2,...,LENWRK.
C
C **************************************************************
C
C Parámetross
CHARACTER*8 SRNAME
PARAMETER (SRNAME='MULTIDIM')
C Argumentos escalares
DOUBLE PRECISION ACC, EPS, FINVAL
INTEGER IFAIL, LENWRK, MAXPTS, MINPTS, NDIM
31
C Arreglos
DOUBLE PRECISION A(NDIM), B(NDIM), WRKSTR(LENWRK)
C Funciones
DOUBLE PRECISION FUNCTN
EXTERNAL FUNCTN
C Escalares locales
DOUBLE PRECISION ABSERR, DF1, DF2, DIFMAX, F1, F2, F3, F4, HALF,
* LAMDA2, LAMDA4, LAMDA5, ONE, RATIO, RGNCMP,
* RGNERR, RGNERT, RGNVAL, RGNVLT, RGNVOL, RLNDIM,
* SUM1, SUM2, SUM3, SUM4, SUM5, TWO, TWONDM,
* WEIT1, WEIT2, WEIT3, WEIT4, WEIT5, WEITP1,
* WEITP2, WEITP3, WEITP4, ZERO
INTEGER DVAXES, DVAXIS, DVFLAG, FUNCLS, IERROR, J, K,
* MAXAXS, MXRGNS, POINTR, RGNCLS, RULCLS, SBRGNS,
* SUBRGN, SUBTMP, TPONTP, TPONTR
C Arreglos locales
DOUBLE PRECISION CENTER(15), DIF(15), OLDCNT(15), WIDTH(15),
* Z(15)
INTEGER DVCNTL(15), DVCNTR(15)
DATA ZERO, ONE, TWO, HALF/0.0D0, 1.0D0, 2.0D0, 0.5D0/
C
C INICIALIZACION DEL PROGRAMA Y VERIFICACION DE PARAMETEROS
C
FUNCLS = 0
IF (NDIM.LT.2 .OR. NDIM.GT.15) GO TO 580
IF (MINPTS.GT.MAXPTS) GO TO 580
IF (EPS.LE.ZERO) GO TO 580
IF (LENWRK.LT.2*NDIM+4) GO TO 580
TWONDM = TWO**NDIM
RGNVOL = TWONDM
DVFLAG = 1
MAXAXS = 50000
MAXAXS = (MAXAXS-NDIM)/(NDIM+1)
MXRGNS = LENWRK/(2*NDIM+4)
SBRGNS = 0
RGNVLT = ZERO
RGNERT = ZERO
DO 20 J = 1, NDIM
CENTER(J) = (A(J)+B(J))*HALF
DIF(J) = ZERO
WIDTH(J) = (B(J)-A(J))*HALF
DVCNTL(J) = 1
DVCNTR(J) = 1
OLDCNT(J) = CENTER(J)
RGNVOL = RGNVOL*WIDTH(J)
20 CONTINUE
C
C FIN DE INICIALIZACION
C CALCULO DE PARAMETROS DE LAS FORMULAS DE CUADRATURAS
C
RULCLS = 2**NDIM + 2*NDIM*NDIM + 2*NDIM + 1
IF (MAXPTS.LT.RULCLS) GO TO 580
FUNCLS = RULCLS
RLNDIM = NDIM
32
LAMDA2 = SQRT(9.0D0/70.0D0)
LAMDA4 = SQRT(9.0D0/10.0D0)
LAMDA5 = SQRT(9.0D0/19.0D0)
WEIT1 = (12824.0D0-9120.0D0*RLNDIM+400.0D0*RLNDIM*RLNDIM)
* /19683.0D0
WEIT2 = 980.0D0/6561.0D0
WEIT3 = (1820.0D0-400.0D0*RLNDIM)/19683.0D0
WEIT4 = 200.0D0/19683.0D0
WEIT5 = 6859.0D0/19683.0D0/TWONDM
WEITP1 = (729.0D0-950.0D0*RLNDIM+50.0D0*RLNDIM**2)/729.0D0
WEITP2 = 245.0D0/486.0D0
WEITP3 = (265.0D0-100.0D0*RLNDIM)/1458.0D0
WEITP4 = 25.0D0/729.0D0
RATIO = (LAMDA2/LAMDA4)**2
C
C FIN DE CALCULO DE PARAMETROS DE FORMULA DE CUADRATURAS
GO TO 100
C DIVIDIR EN SUBREGIONES Y REALIZAR CALCULOS DE
C CUADRATURAS EN CADA PORCION
C
40 SUBRGN = 1
POINTR = WRKSTR(1)
RGNCLS = RULCLS
RGNVOL = TWONDM
TPONTR = POINTR + 2
DO 60 J = 1, NDIM
TPONTR = TPONTR + 2
CENTER(J) = WRKSTR(TPONTR-1)
WIDTH(J) = WRKSTR(TPONTR)
DVCNTR(J) = 1
DVCNTL(J) = 1
OLDCNT(J) = CENTER(J)
RGNVOL = RGNVOL*WIDTH(J)
60 CONTINUE
DVAXES = WRKSTR(POINTR+2)
IF (DVAXES.LT.0) GO TO 620
80 DVAXIS = DVAXES
DVAXES = DVAXIS/(NDIM+1)
DVAXIS = DVAXIS - (NDIM+1)*DVAXES
DVCNTL(DVAXIS) = 2*DVCNTL(DVAXIS)
RGNCLS = RGNCLS*2
IF (DVAXES.GT.0) GO TO 80
IF (FUNCLS+RGNCLS.GT.MAXPTS) GO TO 600
IF (RGNCLS/RULCLS+SBRGNS-1.GT.MXRGNS) DVFLAG = 2
FUNCLS = FUNCLS + RGNCLS
C
C INICIAR CALCULOS, SEGUN LAS FORMULAS DE CUADRATURAS
100 DO 120 J = 1, NDIM
Z(J) = CENTER(J)
120 CONTINUE
SUM1 = FUNCTN(NDIM,Z)
SUM2 = ZERO
SUM3 = ZERO
DO 140 J = 1, NDIM
33
Z(J) = CENTER(J) - LAMDA2*WIDTH(J)
F1 = FUNCTN(NDIM,Z)
Z(J) = CENTER(J) + LAMDA2*WIDTH(J)
F2 = FUNCTN(NDIM,Z)
Z(J) = CENTER(J) - LAMDA4*WIDTH(J)
F3 = FUNCTN(NDIM,Z)
Z(J) = CENTER(J) + LAMDA4*WIDTH(J)
F4 = FUNCTN(NDIM,Z)
SUM2 = SUM2 + F1 + F2
SUM3 = SUM3 + F3 + F4
DF1 = F1 + F2 - TWO*SUM1
DF2 = F3 + F4 - TWO*SUM1
DIF(J) = DIF(J) + ABS(DF1-RATIO*DF2)
Z(J) = CENTER(J)
140 CONTINUE
SUM4 = ZERO
DO 200 J = 2, NDIM
Z(J-1) = CENTER(J-1) - LAMDA4*WIDTH(J-1)
DO 160 K = J, NDIM
Z(K) = CENTER(K) - LAMDA4*WIDTH(K)
SUM4 = SUM4 + FUNCTN(NDIM,Z)
Z(K) = CENTER(K) + LAMDA4*WIDTH(K)
SUM4 = SUM4 + FUNCTN(NDIM,Z)
Z(K) = CENTER(K)
160 CONTINUE
Z(J-1) = CENTER(J-1) + LAMDA4*WIDTH(J-1)
DO 180 K = J, NDIM
Z(K) = CENTER(K) - LAMDA4*WIDTH(K)
SUM4 = SUM4 + FUNCTN(NDIM,Z)
Z(K) = CENTER(K) + LAMDA4*WIDTH(K)
SUM4 = SUM4 + FUNCTN(NDIM,Z)
Z(K) = CENTER(K)
180 CONTINUE
Z(J-1) = CENTER(J-1)
200 CONTINUE
SUM5 = ZERO
DO 220 J = 1, NDIM
Z(J) = CENTER(J) - LAMDA5*WIDTH(J)
220 CONTINUE
240 DO 260 J = 2, NDIM
IF (Z(J-1).LT.CENTER(J-1)+WIDTH(J-1)) GO TO 280
Z(J-1) = CENTER(J-1) - LAMDA5*WIDTH(J-1)
Z(J) = Z(J) + TWO*LAMDA5*WIDTH(J)
260 CONTINUE
IF (Z(NDIM).GT.CENTER(NDIM)+WIDTH(NDIM)) GO TO 300
280 SUM5 = SUM5 + FUNCTN(NDIM,Z)
Z(1) = Z(1) + TWO*LAMDA5*WIDTH(1)
GO TO 240
300 RGNVAL = RGNVOL*(WEIT1*SUM1+WEIT2*SUM2+WEIT3*SUM3+WEIT4*SUM4+
* WEIT5*SUM5)
RGNCMP = RGNVOL*(WEITP1*SUM1+WEITP2*SUM2+WEITP3*SUM3+WEITP4*SUM4)
RGNERR = ABS(RGNVAL-RGNCMP)
C
C FINALIZACION DE CALCULOS CON CUADRATURAS
34
C ALMACENAMIENTO DE LOS RESULTADOS
C
RGNVLT = RGNVLT + RGNVAL
RGNERT = RGNERT + RGNERR
IF (DVFLAG.EQ.0) GO TO 340
IF (DVFLAG.EQ.2) GO TO 500
POINTR = MXRGNS + SBRGNS*(2*NDIM+3) + 1
SBRGNS = SBRGNS + 1
WRKSTR(SBRGNS) = POINTR
SUBRGN = SBRGNS
TPONTR = POINTR + 2
DO 320 J = 1, NDIM
TPONTR = TPONTR + 2
WRKSTR(TPONTR-1) = CENTER(J)
WRKSTR(TPONTR) = WIDTH(J)
320 CONTINUE
340 WRKSTR(POINTR) = RGNERT
WRKSTR(POINTR+1) = RGNVLT
C DEFINIR LA DIRECCION
DIFMAX = ZERO
DO 380 J = 1, NDIM
IF (DIFMAX.GT.DIF(J)) GO TO 360
DIFMAX = DIF(J)
DVAXIS = J
360 DIF(J) = ZERO
380 CONTINUE
TPONTR = POINTR + 2*(DVAXIS+1)
WRKSTR(TPONTR) = WIDTH(DVAXIS)*HALF
WRKSTR(TPONTR-1) = CENTER(DVAXIS) - WRKSTR(TPONTR)
IF (DVFLAG.NE.2) GO TO 400
DVAXES = WRKSTR(POINTR+2)
IF (DVAXES.GT.MAXAXS) DVAXES = -1
DVAXIS = DVAXIS + (NDIM+1)*DVAXES
400 WRKSTR(POINTR+2) = DVAXIS
IF (DVFLAG.EQ.1) GO TO 460
C DEFINIR EN LA LISTA DE SUBREGIONES A LA SIGUIENTE
420 SUBTMP = 2*SUBRGN
IF (SUBTMP.GT.SBRGNS) GO TO 480
TPONTR = WRKSTR(SUBTMP)
IF (SUBTMP.EQ.SBRGNS) GO TO 440
TPONTP = WRKSTR(SUBTMP+1)
IF (WRKSTR(TPONTR).GE.WRKSTR(TPONTP)) GO TO 440
SUBTMP = SUBTMP + 1
TPONTR = TPONTP
440 IF (RGNERT.GE.WRKSTR(TPONTR)) GO TO 480
WRKSTR(SUBTMP) = POINTR
WRKSTR(SUBRGN) = TPONTR
SUBRGN = SUBTMP
GO TO 420
460 SUBTMP = SUBRGN/2
IF (SUBTMP.LT.1) GO TO 480
TPONTR = WRKSTR(SUBTMP)
IF (RGNERT.LE.WRKSTR(TPONTR)) GO TO 480
WRKSTR(SUBTMP) = POINTR
35
WRKSTR(SUBRGN) = TPONTR
SUBRGN = SUBTMP
GO TO 460
480 RGNVLT = ZERO
RGNERT = ZERO
IF (DVFLAG.EQ.2) GO TO 540
DVFLAG = 1 - DVFLAG
500 CENTER(1) = CENTER(1) + TWO*WIDTH(1)
DVCNTR(1) = DVCNTR(1) + 1
DO 520 J = 2, NDIM
IF (DVCNTR(J-1).LE.DVCNTL(J-1)) GO TO 100
DVCNTR(J-1) = 1
CENTER(J-1) = OLDCNT(J-1)
DVCNTR(J) = DVCNTR(J) + 1
CENTER(J) = CENTER(J) + TWO*WIDTH(J)
520 CONTINUE
IF (DVCNTR(NDIM).LE.DVCNTL(NDIM)) GO TO 100
CENTER(NDIM) = OLDCNT(NDIM)
IF (DVFLAG.EQ.2) GO TO 340
C
C FIN DE CALCULOS SEGUN LA CUADRATURA
C VERIFICAR LA POSIBILIDAD DE TERMINAR CALCULOS
C
540 ACC = ONE
ABSERR = ZERO
FINVAL = ZERO
POINTR = MXRGNS + 1
TPONTR = 2*NDIM + 3
DO 560 J = 1, SBRGNS
ABSERR = ABSERR + WRKSTR(POINTR)
FINVAL = FINVAL + WRKSTR(POINTR+1)
POINTR = POINTR + TPONTR
560 CONTINUE
IF (ABS(FINVAL).GT.1.0D32) ACC = ABSERR/ABS(FINVAL)
IF (ABSERR.EQ.ZERO) ACC = ZERO
IF (ACC.GT.EPS .OR. FUNCLS.LT.MINPTS) GO TO 40
C
C FIN DEL CICLO
C
C PUNTO DE TERMINACION, DEFINIR IFAIL Y RETURN
C
IERROR = 0
GO TO 640
580 IERROR = 1
GO TO 640
600 IERROR = 2
GO TO 640
620 IERROR = 3
640 MINPTS = FUNCLS
IFAIL=IERROR
RETURN
END
Realizamos una serie de simulaciones, para analizar la eficiencia del programa. Como ejemplo calculamos la integral
36
I dx dx dx x x xD D D
1 2 1
2
2
2 2... exp ( ... ) (3.12)
con los siguientes valores para el parámetro = 1, 4, 9, 16 y D = 2, 3, 4. Esta integral tiene
valor exacto
I D
D
2
(3.13)
A continuación presentamos el texto del programa principal y la función subintegral.
$DEBUG
C
C PRUEBA DE UN PROGRAMA MULTIDIM
C CALCULAR INTEGRAL TRIDIMENCIONAL CON FUNCION GAUSSIANA
C
c PARAMETER (NDIM=3)
IMPLICIT REAL*8 (A-H,O-Z)
DIMENSION A(3), B(3), WRKSTR(5000)
COMMON /PPP/ PAR
EXTERNAL FUN
pi=4.0d0*DATAN(1.0d0)
NDIM=3
LENWRK=5000
R=20.0d0
A(1)=-R
A(2)=-R
A(3)=-R
B(1)=R
B(2)=R
B(3)=R
MINPTS=10000
MAXPTS=1000000
EPS=1.0d-10
OPEN(1,FILE='MULT.RES')
WRITE(1,*) 'DIMENSION = ',NDIM
DO I=1,5
PAR=1.0D0*I*I
CALL MULTIDIM(NDIM,A,B,MINPTS,MAXPTS,FUN,EPS,ACC,LENWRK,
* WRKSTR,FINVAL,IFAIL)
WRITE(*,*)PAR, FINVAL,pi*dsqrt(pi/PAR**3),MINPTS,IFAIL
WRITE(1,1)PAR, FINVAL,pi*dsqrt(pi/PAR**3),MINPTS,IFAIL
END DO
READ(*,*)
1 FORMAT(2X,F4.1,2F18.9,2I10)
STOP
END
C
C
C
37
REAL*8 FUNCTION FUN(NDIM,Z)
IMPLICIT REAL*8 (A-H,O-Z)
DIMENSION Z(NDIM)
COMMON /PPP/ PAR
c FUN=3.0D0/2.0D0*DSQRT(1.0d0-Z(1)**2-Z(2)**2-Z(3)**2)
c R=dsqrt((Z(1)**2+Z(2)**2+Z(3)**2))
R=Z(1)**2+Z(2)**2+Z(3)**2
FUN=dexp(-par*R)
RETURN
END
C
C
Los resultados se presentan en la tabla 3.2. En la segunda columna se indican los resultados del programa MULTIDIM, en la
tercera los resultados exactos y en la última, el número de cálculos de la función subintegral, el cual es proporcional al tiempo
de cómputo.
Tabla 3.2
DIMENSION = 3
Alfa MULTIDIM EXACTO NOFUN
1.0 5.568327735 5.568327997 999471
4.0 .696040962 .696041000 996831
9.0 .206234370 .206234370 987525
16.0 .087005099 .087005125 554763
25.0 .044546621 .044546624 608751
IV. METODO DE MONTE-CARLO
Consideremos un recinto G en un espacio de D dimensiones y un punto arbitrario dentro del recinto P x x xD( , ,..., )1 2 .
Calculemos la integral, I
I f p p dpG
( ) ( ) (4.1)
donde ( )p es la densidad de distribución de probabilidades, definida G, de tal manera, que
( ) ( ) p dp d p
G G
1 (4.2)
Anotemos, que cualquier integral, f p dpG
( )
, se puede considerar del tipo (4.1), con distribución homogénea, ( )p = 1/VG
donde VG es el volumen en el recinto G. Consideremos a P como un vector aleatorio, con distribución ( )
P . De esta
manera, la integral (4.1), se puede interpretar como el valor promedio de una función, f P( )
. Es decir, I f P ( )
. El
método Monte-Carlo, utiliza dos diferentes algoritmos para hacer este cálculo: uno se llama método Monte-Carlo simple y el
otro el geométrico.
38
4.1 Método Monte-Carlo Simple
En este método, se generan N vectores aleatorios independientes, P P PN1 2, ,..., , con una distribución, ( )
P y se toma
como valor aproximado la estimación de la integral, a
N i
i
N
Nf P
1
1
( )
(4.3)
Según la ley de grandes números, para N , N f P I ( )
, pero para cualquier N finito, N no coincide con I.
En una serie de N experimentos, con un conjunto de vectores aleatorios, Pi , se obtiene un valor N y con otro conjunto
Pi ,
otro N . En este sentido, N se puede considerar una magnitud aleatoria, con valor promedio, N f P I ( ) . Como
cualquier magnitud aleatoria, N tiene varianza, 2 2 ( )N I , diferente de cero y el valor se puede interpretar como
la precisión del cálculo de la integral (4.1), con la estimación (4.3). Teniendo en cuenta que los vectores Pi , son
independientes, es decir, f P f P f P f Pi j i i j j i j( ) ( ) ( ) ( ), ,
2 2 y que, I f P ( )
, se obtiene
f N ; f f P f P 22
( ) ( )
(4.4)
Según el teorema central de límite, el valor de N definido en (4.3) para, números grandes de N, tiene una distribución
normal y con una probabilidad de 99,7%
IN
N
f
3 (4.5)
En algoritmos autoadaptables de Monte-Carlo, las sumas (4.3) se calculan dos veces para los N y 4N experimentos. Usando
(4.5), se obtiene,
N Ic
N ; 4
2N I
c
N , (4.6)
la constante c depende del tipo de la función f P( )
. Excluyendo a I de las igualdades (4.6), encontramos que el error de
estimación, 4 N , es igual a c
N2= N - 4 N , por eso, la estimación, 4 N , puede tomarse como el valor aproximado I
con precisión , si se cumple la siguiente condición,
N N 4 < ; I 4 N (4.7)
Se debe anotar que el proceso de cálculo, converge muy lentamente, usando la condición (4.7). Según (4.5), este proceso se
detiene cuando, 3 f N , es decir para N > 9 f
2 / 2. Por ejemplo para una precisión muy moderada, = 0.001 y
f
2 = 1, tenemos N > 107. Esto implica, un tiempo de cálculo, aproximadamente de 1 minuto, para un computador de 100
Mhz.
39
A continuación presentamos un programa ejemplo, en el cual se realiza un algoritmo de Monte-Carlo simple, para calcular
una integral con una función gaussiana 4-dimensional, a través de las fórmulas (4.3) y (4.7).
EJEMPLO
$DEBUG
C
C TEST - PARA PROGRAMA MONTE_CARLO_SIMPLE
C CALCULO DE UNA INTEGRAL 4 - DIMENSIONAL CON UNA FUNCION
C GAUSSIANA
C
PARAMETER (NDIM=4)
IMPLICIT REAL*8 (A-H,O-Z)
DIMENSION A(NDIM), B(NDIM)
c INTEGER*4 NOFUN
COMMON /PPP/ PAR,EXACT
EXTERNAL FUN
pi=4.0d0*DATAN(1.0d0)
LENWRK=15000
C Fronteras de un hiperrectángulo 4 -dimensional
R=0.1d0
A(1)=-R
A(2)=-R
A(3)=-R
A(4)=-R
B(1)=R
B(2)=R
B(3)=R
B(4)=R
OPEN(1,FILE='MULT.RES')
WRITE(1,*) 'DIMENSION = ',NDIM
c La precisión requerida
EPS=1.0d-3
c Ciclo para 5 parámetros de la función gaussiana
c NDIM - dimensional
DO I=1,5
PAR=1.0D0*I*I
exact=(Dsqrt(pi/PAR)*ERF(R*DSQRT(PAR)))**ndim
CALL MONTE_CARLO_SIMPLE(NDIM,A,B,FUN,EPS,FINVAL,NOFUN)
WRITE(*,*)PAR, FINVAL,EXACT,NOFUN
WRITE(1,1)PAR, FINVAL,EXACT,NOFUN
END DO
READ(*,*)
1 FORMAT(2X,F4.1,2F18.9,I10)
STOP
END
C
SUBROUTINE MONTE_CARLO_SIMPLE(NDIM,A,B,FUN,EPS,FINVAL,NOFUN)
C
C METODO MONTE-CARLO SIMPLE PARA CALCULAR UNA INTEGRAL
C MULTIDIMENSIONAL
C
C B(1) B(2) B(NDIM)
40
C I I ... I FUN(NDIM,X) DX(NDIM)...DX(2)DX(1)
C A(1) A(2) A(NDIM)
C
C PARAMETROS DE ENTRADA:
C -----------------------
C NDIM INTGER, NUMERO DE VARIABLES, > 0
C A REAL*8, ARREGLO DE LIMITES INFERIORES CON DIMENSION NDIM
C B REAL*8, ARREGLO DE LIMITES SUPERIORES CON DIMENSION NDIM
C FUN REAL*8, FUNCION SUBINTEGRAL DEFINIDA POR EL USUARIO.
C DEBE SER DECLARADA COMO EXTERNA. TAMBIEN DEBE TENER
C COMO PARAMETROS (NDIM,X), DONDE X ES UN ARREGLO DE
C DIMENSION NDIM
C EPS REAL*8, LA PRECISION RELATIVA REQUERIDA
C
C PARAMETROS DE ENTRADA:
C -------------------------
C FINVAL REAL*8, VALOR DE LA INTEGRAL ENCONTRADA
C NOFUN INTGER, NUMERO DE ACCESOS PARA CALCULAR (NUMERO DE
C SIMULACIONES) LA FUNCION SUBINTEGRAL PARA ALCANZAR
C LA PRECISION EPS
IMPLICIT REAL*8 (A -H, O-Z)
c INTEGER*4 NOFUN
REAL RAND
DIMENSION Z(20),A(NDIM),B(NDIM)
COMMON /PPP/ PAR,EXACT
EXTERNAL FUN
C
C NUMERO INICIAL DE SIMULACIONES MONTE CARLO
N=100000
SP=0.0d0
NOFUN=N
k=1
10 DO I=1,N
C
C GENERAR NDIM NUMEROS ALEATORIOS PARA FORMAR EL VECTOR ALEATORIO
C
DO J=1,NDIM
CALL RANDOM(RAND)
Z(J)=RAND*(B(J)-A(J))+A(J)
END DO
C
C CALCULAR EL VALOR DE LA FUNCION PARA EL VECTOR ALEATORIO
C
Y=FUN(NDIM,Z)
SP=SP+Y
END DO
C
C ESTIMAR VALOR DE LA INTEGRAL PARA NOFUN SIMULACIONES
C
RPNEW=SP/NOFUN
C
C SI ES LA PRIMERA SERIE DE SIMULACIONES, ENTONCES AUMENTAR
C EL NUMERO DE SIMULACIONES A CUATRO VECES Y VOLVER A GENERAR
C NUEVOS VECTORES ALEATORIOS
41
C
if (k.eq.1) then
RPOLD=RPNEW
k=k+1
N=3*NOFUN
NOFUN=NOFUN+N
go to 10
end if
C
C CALCULAR LOS VALORES DE LAS INTEGRALES PARA NOFUN Y 4*NOFUN SIMULACIONES
C
DO i=1,NDIM
RP2=RPNEW*(B(I)-A(I))
RP1=RPOLD*(B(I)-A(I))
END DO
C
C VERIFICACION DE LA PRECISION DESEADA
C
IF(DABS(RP2-RP1)/RP2.GT.EPS) THEN
N=N*3
NOFUN=NOFUN+N
RPOLD=RPNEW
WRITE(*,*) RP2,RP1,exact
GO TO 10
END IF
FINVAL=RP2
RETURN
END
C
C FUNCION SUIBINTEGRAL GAUSSIANA EN NDIM - DIMENSIONES
C
REAL*8 FUNCTION FUN(NDIM,Z)
IMPLICIT REAL*8 (A-H,O-Z)
DIMENSION Z(NDIM)
COMMON /PPP/ PAR,EXACT
R=Z(1)**2+Z(2)**2+Z(3)**2+Z(4)**2
FUN=dexp(-par*R)
RETURN
END
C
REAL*8 FUNCTION ERF(XX)
C
C ERF(X) CALCULO 2.0/SQRT(PI) MULTIPLICADO POR INTEGRAL
C DESDE 0 HASTA X PARA FUNCION SUBINTEGRAL EXP(-X**2).
C USANDO APPROXIMACIONES RACIONALES.
C
C DESCRIPCION DE PARAMETROS
C
C X MAY BE ANY REAL*8 VALUE
C
IMPLICIT REAL*8 (A -H, O - Z)
DIMENSION P1(4),Q1(4),P2(6),Q2(6),P3(4),Q3(4)
DATA (P1(I),I=1,4)/242.6679552305318,21.97926161829415,6.996383488
42
1619136,-3.560984370181539E-02/,
2(Q1(I),I=1,4)/215.0588758698612,91.16490540451490,15.0827976304077
39,1.0/,
4(P2(I),I=1,6)/22.898992851659,26.094746956075,14.571898596926,4.26
577201070898,.56437160686381,-6.0858151959688E-06/,
6(Q2(I),I=1,6)/22.898985749891,51.933570687552,50.273202863803,26.2
788795758761,7.5688482293618,1.0/,
8(P3(I),I=1,4)/-1.21308276389978E-2,-.1199039552681460,-.2439110294
988626,-3.24319519277746E-2/,
1(Q3(I),I=1,4)/4.30026643452770E-02,.489552441961437,1.437712279371
218,1.0/
DATA SQPI/.564189583547756/
C
X=DABS(XX)
IF(X.GT.6.0)GO TO 320
X2=X*X
IF(X.GT.4.0)GO TO 300
IF(X.GT..46875)GO TO 200
A= X*(P1(1)+X2*(P1(2)+X2*(P1(3)+X2*P1(4))))
A=A/(Q1(1)+X2*(Q1(2)+X2*(Q1(3)+X2*Q1(4))))
IF(XX.LT.0.)A=-A
ERF=A
GO TO 400
200 A=DEXP(-X2)*(P2(1)+X*(P2(2)+X*(P2(3)+
$ X*(P2(4)+X*(P2(5)+X*P2(6))))))
A=A/(Q2(1)+X*(Q2(2)+X*(Q2(3)+X*(Q2(4)+X*(Q2(5)+X*Q2(6))))))
ERF=DSIGN((1.0-A),XX)
GO TO 400
300 XI2=1./X2
R=XI2*(P3(1)+XI2*(P3(2)+XI2*(P3(3)+XI2*P3(4))))/(Q3(1)+XI2*(Q3(2)+
1XI2*(Q3(3)+XI2*Q3(4))))
A=DEXP(-X2)*(SQPI+R)/X
ERF=DSIGN((1.0-A),XX)
GO TO 400
320 CONTINUE
ERF=XX/X
400 RETURN
END
En este programa también se calcula el valor exacto de la integral gaussiana para D dimensiones,
dx dx dx x x x erf RR
R
R
R
DR
R
D
D
1 2 12
22 2
... exp ...
(4.8)
Los números aleatorios con distribución homogénea, en el intervalo (0,1), se generan a través del subprograma, RANDOM
incorporado en la biblioteca de FORTRAN. Los experimentos numéricos mostraron poca eficiencia de este algoritmo y por
eso, confeccionamos otro programa, usando el método Monte-Carlo geométrico.
4.2 Método Monte-Carlo Geométrico
43
Interpretemos la integral (4.1), como el volumen de un hipercilindro, en un espacio de, D+1 dimensiones, con límite inferior,
xD+1 = 0 y superior xD+1 = f P( )
. El vectorP también contiene la dimensión D, y se define dentro del recinto G, de D
dimensiones. Supongamos que la función f P( )
está acotada en el recinto G,
0 f P( )
c (4.9)
En este caso, se puede considerar un hipercilindro recto, ~G en un espacio de D+1 dimensiones,
~( , )G G c 0 . Ahora
generemos los vectores aleatorios de D + 1 dimensiones,
Q con densidad de distribución,
( ) ( , ) ( ) Q P x
cPD D 1 1
1. La proyección del vector
P D+1 , sobre el subespacio G, es el vector
P , con
distribución (P ). La coordenada xD+1, tiene densidad de distribución homogénea,
1
c dentro del intervalo (0,c).
Generamos N vectores, Q Q QN1 2, ,..., , independientes y denotemos por Np, el número de vectores, que están bajo la
superficie, xD+1 = f P( )
y tomemos como valor la estimación de la integral (4.1)
N
p
G
cN
NV , (4.10)
VG es el volumen del cilindro ~G . Según la ley de números grandes, para N , el límite de N es igual al volumen del
hipercilindro (4.9). Se puede demostrar que las fórmulas (4.6) y (4.7) son válidas, para este caso y por eso, el algoritmo de
cálculo, difiere poco del algoritmo del método de Monte-Carlo simple. Presentamos un programa ejemplo que realiza el
algoritmo Monte-Carlo geométrico.
$ DEBUG
C TEST - PARA PROGRAMA MONTE_CARLO_GEOMET
C CALCULO DE UNA INTEGRAL 4 - DIMENSIONAL PARA UNA FUNCION
C GAUSSIANA
C
PARAMETER (NDIM=5)
IMPLICIT REAL*8 (A-H,O-Z)
DIMENSION A(NDIM), B(NDIM)
c INTEGER*4 NOFUN
COMMON /PPP/ PAR,EXACT
EXTERNAL FUN
pi=4.0d0*DATAN(1.0d0)
LENWRK=15000
C Fronteras de un hiperrectángulo 4 -dimencional
R=1.0d0
A(1)=-R
A(2)=-R
A(3)=-R
A(5)=0.0d0
A(4)=-R
B(1)=R
B(2)=R
B(3)=R
44
B(4)=R
B(5)=1.0d0
OPEN(1,FILE='MULT.RES')
WRITE(1,*) 'DIMENSION = ',NDIM
c Precisión requerida
EPS=1.0d-3
c Ciclo para 5 parámetros de la función gaussiana
c NDIM - dimensional
DO I=1,5
PAR=1.0D0*I*I
exact=(Dsqrt(pi/PAR)*ERF(R*DSQRT(PAR)))**ndim
CALL MONTE_CARLO_GEOMET(NDIM,A,B,FUN,EPS,FINVAL,NOFUN)
WRITE(*,*)PAR, FINVAL,EXACT,NOFUN
WRITE(1,1)PAR, FINVAL,EXACT,NOFUN
END DO
READ(*,*)
1 FORMAT(2X,F4.1,2F18.9,I10)
STOP
END
C
C
C
SUBROUTINE MONTE_CARLO_GEOMET(NDIM,A,B,FUN,EPS,FINVAL,NOFUN)
c
C METODO MONTE-CARLO GEOMETRICO PARA CALCULAR UNA INTEGRAL
C MULTIDIMENSIONAL
C
C B(1) B(2) B(NDIM)
C I I ... I FUN(NDIM,X) DX(NDIM)...DX(2)DX(1)
C A(1) A(2) A(NDIM)
C
C PARAMETROS DE ENTRADA:
C -----------------------
C NDIM INTGER, NUMERO DE VARIABLES, > 0
C A REAL*8, ARREGLO DE LIMITES INFERIORES CON DIMENSION NDIM
C B REAL*8, ARREGLO DE LIMITES SUPERIORES CON DIMENSION NDIM
C FUN REAL*8, FUNCION SUBINTEGRAL, DEFINIDA POR EL USUARIO.
C DEBE SER DECLARADA COMO EXTERNA . TAMBIEN TIENE COMO
c PARAMETROS (NDIM,X), DONDE X ES UN ARREGLO DE DIMENSION
C NDIM
C EPS REAL*8, LA PRECISION RELATIVA REQUERIDA
C
C PARAMETROS DE SALIDA:
C -------------------------
C FINVAL REAL*8, VALOR DE INTEGRAL ENCONTRADO
C NOFUN INTGER, NUMERO DE ACCESOS PARA CALCULAR (NUMERO DE
C SIMULACIONES) DE LA FUNCION SUBINTEGRAL PARA ALCANZAR
C LA PRECISION EPS
C
IMPLICIT REAL*8 (A -H, O-Z)
c INTEGER*4 NOFUN
REAL RAND
DIMENSION Z(15),A(NDIM),B(NDIM)
COMMON /PPP/ PAR,EXACT
45
EXTERNAL FUN
C
C DEFINIR LA FRONTERA SUPERIOR DEL HIPERCILINDRO
C
CN=B(5)
C
C NUMERO INICIAL DE SIMULACIONES
C
N=100000
SP=0.0d0
NOFUN=N
k=1
C
C INICIAR CICLO DE SIMULACIONES
C
10 DO I=1,N
C
C GENERAR, NDIM, NUMEROS ALEATORIOS PARA FORMAR EL VECTOR
C
DO J=1,NDIM
CALL RANDOM(RAND)
Z(J)=RAND*(B(J)-A(J))+A(J)
END DO
C
C ENCONTRAR EL VALOR DE LA FUNCION PARA EL VECTOR SIMULADO
C
Y=FUN(NDIM-1,Z)
C
C VERIFICAR QUE EL PUNTO ESTE CONTENIDO EN EL RECINTO
C
IF(Z(NDIM).LE.Y) NP=NP+1
END DO
C
C CALCULO DEL PORCENTAJE DE PUNTOS DENTRO EL RECINTO
C
RPNEW=CN*NP/NOFUN
if (k.eq.1) then
RPOLD=RPNEW
k=k+1
N=3*NOFUN
NOFUN=NOFUN+N
go to 10
end if
C
C CALCULAR EL VALOR DE LA INTEGRAL PARA NOFUN Y 4*NOFUN
C SIMULACIONES
C
DO i=1,NDIM-1
RP2=RPNEW*(B(I)-A(I))
RP1=RPOLD*(B(I)-A(I))
END DO
C
C VERIFICAR PRECISION ALCANZADA
C
46
IF(DABS(RP2-RP1)/RP2.GT.EPS) THEN
N=NOFUN*3
NOFUN=NOFUN+N
RPOLD=RPNEW
WRITE(*,*) RP2,RP1,exact
GO TO 10
END IF
FINVAL=RP2
RETURN
END
4.3 Programa Autoadaptable de Monte-Carlo
Los programas anteriores son muy lentos y para alcanzar una precisión determinada se necesitan cálculos, del orden de 107
108 de la función subintegral. Para mejorar este cálculo hay dos opciones: usar un algoritmo autoadaptable, o buscar un
generador especial de vectores aleatorios para cada función subintegral, que se ajuste a la función. En ambos casos, se busca
una distribución inhomogénea, de tal forma que la distribución sea más densa donde la función varíe bruscamente y menos
densa en regiones, donde la función es suave. En este informe consideramos sólo la primera opción, puesto que los algoritmos
autoadaptables, son más generales y no dependen del tipo de la función subintegral.
La construcción de algoritmos autoadaptables para el método Monte-Carlo, son muy parecidos a los usados en las fórmulas de
cuadraturas, los cuales tienen la estructura de un árbol recursivo, con 2D ramas en cada nudo. En el proceso recursivo de
iteraciones, el hiperrectángulo se divide en 2n hiperrectángulos iguales y a cada uno de estos, se le aplica el método de Monte-
Carlo. En el texto del programa del método autoadaptable de Monte-Carlo se hacen comentarios para explicar el
funcionamiento del programa.
Como ejemplo de aplicación consideramos el cálculo de una función gaussiana,
f x x x x x xD D( , ,..., ) exp ( ... ),1 2 1
2
2
2 2 dentro del rectángulo -R < xi < R, (R = 1.0), con = 1, 4, 9, 16 y 25, en
un espacio de dimensión D = 3 y 4. Esta función, para grandes valores de , es singular en el origen de coordenadas y por
eso, los programas no autoadaptables no pueden calcular las integrales con buena precisión. Los cálculos de la integral los
presentamos después del texto del programa, donde se puede apreciar la eficiencia del algoritmo. En la columna número 4 de
los resultados se da el número de simulaciones, Nofun, usadas para alcanzar la precisión Relerr presentada en la columna 5.
Se ve el crecimiento rápido Nofun, con el aumento del parámetro .
$DEBUG
C
C TEST - PROGRAMA_AUTOADAP_ MONTE_CARLO
C CALCULO DE UNA INTEGRAL GAUSSIANA 4 - DIMENCIONAL
C
PARAMETER (NDIM=4)
PARAMETER (LENWRK=20000)
C
IMPLICIT REAL*8 (A-H,O-Z)
DIMENSION A(NDIM), B(NDIM),WRKSTR(LENWRK)
COMMON /PPP/ PAR,EXACT
EXTERNAL FUN
pi=4.0d0*DATAN(1.0d0)
C Fronteras de un hiperrectángulo 4 -dimencional
R=1.0d0
A(1)=-R
A(2)=-R
47
A(3)=-R
A(4)=-R
B(1)=R
B(2)=R
B(3)=R
B(4)=R
MINPTS=100000
MAXPTS=5000000
OPEN(1,FILE='MULT.RES')
WRITE(1,*) 'DIMENSION = ',NDIM
c Precisión deseada
RELEPS=1.0d-3
c Ciclo para 5 parámetros de la función Gaussiana NDIM - dimensional
DO I=1,5
PAR=1.0D0*I*I
exact=(Dsqrt(pi/PAR)*ERF(R*DSQRT(PAR)))**ndim
CALL MONTE_CARLO_ADAPT(NDIM,A,B,MINPTS,MAXPTS,
* FUN,RELEPS,RELERR,LENWRK,WRKSTR,FINVAL,IFAIL)
WRITE(*,*)PAR, FINVAL,EXACT,MINPTS,RELERR
WRITE(1,1)PAR, FINVAL,EXACT,MINPTS,RELERR
END DO
READ(*,*)
1 FORMAT(2X,F4.1,2F18.9,I10,D14.2)
STOP
END
C
C FUNCION SUIBINTEGRAL GAUSSIANA EN NDIM - DIMENSIONES
C
REAL*8 FUNCTION FUN(NDIM,Z)
IMPLICIT REAL*8 (A-H,O-Z)
DIMENSION Z(NDIM)
COMMON /PPP/ PAR,EXACT
R=Z(1)**2+Z(2)**2+Z(3)**2+Z(4)**2
c R=Z(1)**2+Z(2)**2+Z(3)**2
FUN=dexp(-par*R)
RETURN
END
SUBROUTINE MONTE_CARLO_ADAPT(NUMVAR,A,B,MINPTS,MAXPTS,
* FUNCTN,RELEPS,RELERR,LENWRK,WRKSTR,FINVAL,IFAIL)
C
C
C METODO AUTOADAPTABLE DE MONTE CARLO PARA CALCULAR UNA
C INTEGRAL MULTIPLE
C
C B(1) B(2) B(NUMVAR)
C I I ... I FUNCTN(NUMVAR,X) DX(NUMVAR)...DX(2)DX(1)
C A(1) A(2) A(NUMVAR)
C
C PARAMETR0S DE ENTRADA:
C --------------------------
C NUMVAR INTEGER, EL NUMERO DE VARIABLES DEBE SER MAYOR QUE 0
C A REAL*8, ARREGLO DE DIMENSION, NUMVAR,
C DE LOS LIMITES SUPERIORES
C B REAL*8, ARREGLO DE DIMENSION NUMVAR,
48
C DE LOS LIMITES INFERIORES
C MINPTS INTEGER, NUMERO MINIMO DE CALCULOS PERMITIDOS DE LA
C FUNCION
C MAXPTS INTEGER, EL NUMERO MAXIMO DE CALCULOS PERMITIDOS DE
C LA FUNCION, DEBE SER AL MENOS, IGUAL A 4*NUMVAR+4
C FUNCTN REAL*8, FUNCION SUBINTEGRAL DEFINIDA POR EL USUARIO Y
C DECLARADA COMO EXTERNA. DEBE TENER LA FORMA
C FUNCTN(NUMVAR,X), DONDE X ES UN ARREGLO REAL*8 DE
C DIMENSION NUMVAR.
C RELEPS REAL*8, PRECISION RELATIVA REQUERIDA
C LENWRK INTEGER, LONGITUD DEL ARREGLO AUXILIAR WRKSTR,
C DEBE SER 3*NUMVAR*((MAXPTS/4)**(1/NUMVAR))+7*NUMVAR
C WRKSTR REAL*8, ARREGLO AUXILIAR DE DIMENSION(LENWRK).
C
C PARAMETROS DE SALIDA:
C -------------------------
C RELERR REAL*8, PRECISION RELATIVA ALCANZADA EN EL CALCULO DE
C FINVAL
C FINVAL REAL*8, VALOR DE LA INTEGRAL ENCONTRADA.
C IFAIL INTEGER, VERIFICAR FALLAS EN EL PROGRAMA
C IFAIL=0, SALIDA NORMAL, CUANDO RELERR ES MENOR QUE, RELEPS,
C EL NUMERO DE CALCULOS DE LA FUNCION, MAXPTS,
C IFAIL=1,SI NUMVAR.LT.1,MINPTS.GE.OMAXPTS,LENWRK.LT.10*NUMVAR
C O MAXPTS.LT.4*(NUMVAR+1) O RELEPS.LT.0.0.
C IFAIL=2, SI MAXPTS ES DEMASIADO PEQUEÑO PARA ALCANZAR
C LA PRECISION REQUERIDA.
CHARACTER*6 SRNAME
PARAMETER (SRNAME='D01GBF')
DOUBLE PRECISION FINVAL, RELEPS, RELERR
INTEGER IFAIL, LENWRK, MAXPTS, MINPTS, NUMVAR
DOUBLE PRECISION A(NUMVAR), B(NUMVAR), WRKSTR(LENWRK)
DOUBLE PRECISION FUNCTN
EXTERNAL FUNCTN
INTEGER IERROR
CHARACTER*1 P01REC(1)
INTEGER CHEC
EXTERNAL CHEC
EXTERNAL MNTCRL
C VERIFICAR PARAMETROS INICIALES
IERROR = 1
RELERR = 1.0D0
IF (NUMVAR.LT.1) GO TO 20
IF (LENWRK.LT.10*NUMVAR) GO TO 20
IF (MINPTS.GE.MAXPTS) GO TO 20
IF (MAXPTS.LT.4*NUMVAR+4) GO TO 20
IF (RELEPS.LT.0.0D0) GO TO 20
C
C SI TODOS LOS PARAMETROS INICIALES SON NORMALES ENTONCES
C CALCULAR LA INTEGRAL
C
CALL MNTCRL(NUMVAR,A,B,MINPTS,MAXPTS,FUNCTN,RELEPS,RELERR,
* WRKSTR(1),WRKSTR(NUMVAR+1),WRKSTR(2*NUMVAR+1)
* ,WRKSTR(3*NUMVAR+1),WRKSTR(4*NUMVAR+1)
* ,WRKSTR(5*NUMVAR+1),WRKSTR(6*NUMVAR+1)
49
* ,LENWRK-7*NUMVAR,WRKSTR(7*NUMVAR+1),FINVAL,IERROR)
C
C SALIDA DE FALLAS
C
20 IFAIL = CHEC(IFAIL,IERROR,SRNAME,0,P01REC)
RETURN
END
C
C SUBPROGRAMA PARA CALCULAR LA INTEGRAL
C
SUBROUTINE MNTCRL(NUMVAR,A,B,MINPTS,MAXPTS,FUNCTN, RELEPS,
* RELERR, CNTLIM,COUNTR,LOWER,POINTR,BMNUSA,WIDTH,X,
* LENWRK,WRKSTR,FINVAL,IERROR)
DOUBLE PRECISION FINVAL, RELEPS, RELERR
INTEGER IERROR, LENWRK, MAXPTS, MINPTS, NUMVAR
DOUBLE PRECISION A(NUMVAR), B(NUMVAR), BMNUSA(NUMVAR),
* CNTLIM(NUMVAR), COUNTR(NUMVAR), LOWER(NUMVAR),
* POINTR(NUMVAR), WIDTH(NUMVAR), WRKSTR(LENWRK),
* X(NUMVAR)
DOUBLE PRECISION FUNCTN
EXTERNAL FUNCTN
DOUBLE PRECISION DNMVAR, EFACTR, FUNVAL, HALF, INTEST, ONE,
* QNCRSE, RGNVOL, RLSMPM, RLSMPT, SFACTR, SMALL,
* SMSQRS, SUMFUN, SUMWID, TVALSQ, TVARIN, TVARSQ,
* TWIDTH, TWO, VAREST, VARPRD, VARSQR, VOLUME,
* VRSQRJ, WIDTHJ, ZERO
INTEGER I, INDEX1, INDEX2, INDEX3, INRVLS, INTCLS,
* ITRPTS, J, K, KLOWER, KUPPER, L, MINCNT, MINSMP,
* NEWCNT, POINT, SAMPTS, SBRGNS
C ..FUNCIONES EXTERNAS
DOUBLE PRECISION G05CAF
EXTERNAL G05CAF
DATA ZERO, ONE, TWO/0.0D0, 1.0D0, 2.0D0/
C DATOS INICIALES
INTCLS = 0
MINSMP = 2
C
C
IERROR = 0
HALF = ONE/TWO
SMALL = 1.0D-32
EFACTR = TWO
SAMPTS = MINSMP
IF (LENWRK.EQ.3*NUMVAR) SAMPTS = MAXPTS/2
ITRPTS = SAMPTS*2
VAREST = ZERO
VOLUME = ONE
DNMVAR = ONE/DBLE(NUMVAR)
RLSMPT = DBLE(SAMPTS)
RLSMPM = RLSMPT - 1.0D0
IF (MINPTS.GE.0) GO TO 40
C
C INICIALIZAR INTERVALOS PARA LLAMADAS POSTERIORES
C
50
VAREST = WRKSTR(LENWRK)
DO 20 I = 1, NUMVAR
BMNUSA(I) = B(I) - A(I)
VOLUME = VOLUME*BMNUSA(I)
ITRPTS = ITRPTS*INT(CNTLIM(I))
20 CONTINUE
MINCNT = INT(WRKSTR(LENWRK-1))
SBRGNS = ITRPTS/(2*SAMPTS)
IF (ITRPTS.LE.MAXPTS) GO TO 180
C
C INICIALIZAR INTERVALOS PARA LA PRIMERA LLAMADA
C
40 DO 60 J = 1, NUMVAR
CNTLIM(J) = ONE
BMNUSA(J) = B(J) - A(J)
VOLUME = VOLUME*BMNUSA(J)
60 CONTINUE
INRVLS = NUMVAR
80 DO 100 I = 1, NUMVAR
IF (INRVLS+1.GT.LENWRK/3) GO TO 120
ITRPTS = (ITRPTS*INT(CNTLIM(I)+ONE))/INT(CNTLIM(I))
INRVLS = INRVLS + 1
CNTLIM(I) = CNTLIM(I) + ONE
IF (ITRPTS.GT.MINPTS/2) GO TO 120
100 CONTINUE
GO TO 80
120 INDEX1 = 0
DO 160 J = 1, NUMVAR
NEWCNT = INT(CNTLIM(J))
WIDTHJ = ONE/CNTLIM(J)
DO 140 I = 1, NEWCNT
INDEX1 = INDEX1 + 1
WRKSTR(INDEX1) = WIDTHJ
140 CONTINUE
160 CONTINUE
MINCNT = INT(MIN(TWO,CNTLIM(NUMVAR)))
INRVLS = NUMVAR*MINCNT
SBRGNS = ITRPTS/(2*SAMPTS)
FINVAL = ZERO
RELERR = ZERO
C
C ITERACIONES
C
180 IF (VOLUME.EQ.ZERO) GO TO 700
INTCLS = INTCLS + ITRPTS
INRVLS = 0
DO 200 I = 1, NUMVAR
POINTR(I) = DBLE(INRVLS)
COUNTR(I) = 1.0D0
X(I) = (A(I)+B(I))/TWO
WIDTH(I) = WRKSTR(INRVLS+1)
LOWER(I) = ZERO
INRVLS = INRVLS + INT(CNTLIM(I))
200 CONTINUE
51
C
C INICIAR CICLO DE INTEGRACION
C
DO 280 I = 1, NUMVAR
VARSQR = ZERO
IF (CNTLIM(I).GT.ONE .OR. SAMPTS.GT.MINSMP) GO TO 240
SUMFUN = ZERO
SMSQRS = ZERO
INTCLS = INTCLS + SAMPTS*2
DO 220 J = 1, SAMPTS
CALL RANDOM(RAND)
X(I) = A(I) + BMNUSA(I)*RAND
FUNVAL = FUNCTN(NUMVAR,X)
X(I) = TWO*(A(I)+BMNUSA(I)*HALF) - X(I)
FUNVAL = HALF*(FUNVAL+FUNCTN(NUMVAR,X))
SUMFUN = SUMFUN + FUNVAL
SMSQRS = SMSQRS + FUNVAL*FUNVAL
220 CONTINUE
VARSQR = (SMSQRS*RLSMPT-SUMFUN*SUMFUN)*(VOLUME/RLSMPT)**2
X(I) = (A(I)+B(I))/TWO
240 KLOWER = INRVLS + 1 + INT(POINTR(I))
KUPPER = INRVLS + INT(POINTR(I)+CNTLIM(I))
DO 260 K = KLOWER, KUPPER
WRKSTR(K) = ZERO
INDEX3 = INRVLS + K
WRKSTR(INDEX3) = VARSQR
260 CONTINUE
280 CONTINUE
C
C CICLO PRINCIPAL
C
300 RGNVOL = VOLUME
DO 320 I = 1, NUMVAR
RGNVOL = RGNVOL*WIDTH(I)
320 CONTINUE
SUMFUN = ZERO
SMSQRS = ZERO
DO 380 L = 1, SAMPTS
DO 340 I = 1, NUMVAR
CALL RANDOM(RAND)
X(I) = A(I) + BMNUSA(I)*(LOWER(I)+RAND*WIDTH(I))
340 CONTINUE
FUNVAL = FUNCTN(NUMVAR,X)
DO 360 I = 1, NUMVAR
X(I) = TWO*(A(I)+BMNUSA(I)*(LOWER(I)+HALF*WIDTH(I))) - X(I)
360 CONTINUE
FUNVAL = HALF*(FUNVAL+FUNCTN(NUMVAR,X))
SUMFUN = SUMFUN + FUNVAL
SMSQRS = SMSQRS + FUNVAL*FUNVAL
380 CONTINUE
INTEST = RGNVOL*SUMFUN/RLSMPT
VARSQR = (SMSQRS*RLSMPT-SUMFUN*SUMFUN)*(RGNVOL/RLSMPT)**2
DO 400 I = 1, NUMVAR
INDEX2 = INT(POINTR(I)+COUNTR(I)) + INRVLS
52
WRKSTR(INDEX2) = WRKSTR(INDEX2) + INTEST
INDEX3 = INDEX2 + INRVLS
WRKSTR(INDEX3) = WRKSTR(INDEX3) + VARSQR
400 CONTINUE
DO 440 I = 1, NUMVAR
IF (COUNTR(I).EQ.CNTLIM(I)) GO TO 420
COUNTR(I) = COUNTR(I) + ONE
LOWER(I) = LOWER(I) + WIDTH(I)
INDEX1 = INT(POINTR(I)+COUNTR(I))
WIDTH(I) = WRKSTR(INDEX1)
GO TO 300
420 COUNTR(I) = 1.0D0
LOWER(I) = ZERO
INDEX1 = INT(POINTR(I)+ONE)
WIDTH(I) = WRKSTR(INDEX1)
440 CONTINUE
C
C FIN DEL CICLO PRINCIPAL
C
NEWCNT = INT(CNTLIM(1))
INTEST = ZERO
VARSQR = ZERO
DO 460 I = 1, NEWCNT
INDEX2 = INRVLS + I
INTEST = INTEST + WRKSTR(INDEX2)
INDEX3 = INDEX2 + INRVLS
VARSQR = VARSQR + WRKSTR(INDEX3)
460 CONTINUE
VARSQR = VARSQR/RLSMPM
VARPRD = VAREST*VARSQR
FINVAL = (INTEST+FINVAL*VARPRD)/(ONE+VARPRD)
VARSQR = MAX(VARSQR,ZERO)
RELERR = EFACTR*SQRT(VARSQR/(VARPRD+ONE))/MAX(SMALL,ABS(FINVAL))
IF (RELERR.GT.ONE) RELERR = ONE
VARSQR = MAX(VARSQR,SMALL)
VAREST = (ONE+VARPRD)/VARSQR
C
C VERIFICAR PRECISION ALCANZADA
C
IF (RELERR.LT.RELEPS .AND. INTCLS.GT.MINPTS) GO TO 700
C
C RECALCULAR LOS TAMAÑOS DE LOS INTERVALOS
C
TVARIN = ONE
DO 520 I = 1, NUMVAR
TWIDTH = ZERO
TVARSQ = ZERO
TVALSQ = ZERO
NEWCNT = INT(CNTLIM(I))
DO 480 J = 1, NEWCNT
INDEX1 = INT(POINTR(I)) + J
WIDTHJ = WRKSTR(INDEX1)
INDEX2 = INDEX1 + INRVLS
TVALSQ = TVALSQ + WRKSTR(INDEX2)*WRKSTR(INDEX2)/WIDTHJ
53
INDEX3 = INDEX2 + INRVLS
VRSQRJ = MAX(WRKSTR(INDEX3),SMALL/CNTLIM(I))
TVARSQ = TVARSQ + VRSQRJ/WIDTHJ
SFACTR = SQRT(RLSMPM*VARSQR/(VRSQRJ*CNTLIM(I)))
SFACTR = MAX(HALF,MIN(TWO,SFACTR))
WIDTHJ = WIDTHJ*SFACTR
WRKSTR(INDEX1) = WIDTHJ
TWIDTH = TWIDTH + WIDTHJ
480 CONTINUE
WIDTH(I) = MAX(SMALL,TVALSQ+TVARSQ-INTEST*INTEST)
WIDTH(I) = SQRT(WIDTH(I))/CNTLIM(I)
TVARIN = TVARIN*WIDTH(I)**DNMVAR
DO 500 J = 1, NEWCNT
INDEX1 = INT(POINTR(I)) + J
WRKSTR(INDEX1) = WRKSTR(INDEX1)/TWIDTH
INDEX2 = INDEX1 + INRVLS
WRKSTR(INDEX2) = WRKSTR(INDEX1)
500 CONTINUE
520 CONTINUE
C
C RECALCULAR LOS NUMEROS DE INTERVALOS
C
SFACTR = MIN(TWO,DBLE(MPTS-INTCLS)/DBLE(ITRPTS))
QNCRSE = SFACTR/TVARIN
SBRGNS = INT(SFACTR*DBLE(SBRGNS))
IF (2*SAMPTS*SBRGNS.GT.MAXPTS-INTCLS)
* SBRGNS = INT(SFACTR*DBLE(ITRPTS/(2*SAMPTS)))
IF (2*SAMPTS*SBRGNS.LT.ITRPTS) GO TO 680
540 POINT = 0
ITRPTS = 1
DO 560 I = 1, NUMVAR
SFACTR = MAX(HALF,MIN(TWO,QNCRSE*WIDTH(I)))
NEWCNT = MAX(MINCNT,INT(CNTLIM(I)*SFACTR))
POINT = POINT + NEWCNT
ITRPTS = ITRPTS*NEWCNT
COUNTR(I) = NEWCNT
560 CONTINUE
IF (SBRGNS.GE.ITRPTS) GO TO 580
QNCRSE = QNCRSE*(DBLE(SBRGNS)/DBLE(ITRPTS))**DNMVAR
GO TO 540
580 IF (3*POINT.LE.LENWRK) GO TO 600
QNCRSE = QNCRSE*(DBLE(LENWRK)/DBLE(3*POINT))**DNMVAR
GO TO 540
C
C INCLUIR NUEVOS NUMEROS Y TAMAÑOS DE INTERVALOS
C
600 POINT = 0
ITRPTS = ITRPTS*SAMPTS*2
DO 660 I = 1, NUMVAR
NEWCNT = INT(COUNTR(I))
SUMWID = ONE
DO 640 J = 1, NEWCNT
KLOWER = INT(SUMWID)
INDEX2 = INRVLS + INT(POINTR(I)) + KLOWER - 1
54
WIDTHJ = (DBLE(KLOWER)-SUMWID)*WRKSTR(INDEX2+1)
SUMWID = ONE + DBLE(J)*CNTLIM(I)/COUNTR(I)
KUPPER = INT(SUMWID)
IF (SUMWID.EQ.DBLE(KUPPER)) KUPPER = KUPPER - 1
DO 620 K = KLOWER, KUPPER
INDEX2 = INDEX2 + 1
WIDTHJ = WIDTHJ + WRKSTR(INDEX2)
620 CONTINUE
INDEX1 = POINT + J
WRKSTR(INDEX1) = WIDTHJ - (DBLE(KUPPER+1)-SUMWID)
* *WRKSTR(INDEX2)
640 CONTINUE
POINT = POINT + NEWCNT
CNTLIM(I) = DBLE(NEWCNT)
660 CONTINUE
GO TO 180
C
C FALLAS DEBIDAS A PEQUEÑOS VALORES DE MAXPTS
C
680 IERROR = 2
C
C GUARDAR INFORMACION PARA LAS SIGUIENTES LLAMADAS
C
700 WRKSTR(LENWRK) = VAREST
WRKSTR(LENWRK-1) = DBLE(MINCNT)
MINPTS = INTCLS
RETURN
END
DIMENSION = 3
Monte -Carlo Exacto Nofun Relerr
1.0 3.332302744 3.332307047 148340 .67D-05
4.0 .686334170 .686318933 219564 .44D-04
9.0 .206215707 .206220703 331088 .93D-04
16.0 .086993953 .087005121 484628 .15D-03
25.0 .044553145 .044546624 713956 .19D-03
DIMENSION = 4
Monte -Carlo Exacto Nofun Relerr
1.0 4.977361517 4.977294621 158696 .45D-04
4.0 .605359532 .605389159 236608 .33D-03
9.0 .121851551 .121836202 325532 .95D-03
16.0 .038531020 .038553140 1083168 .76D-03
25.0 .015795589 .015791367 3611508 .55D-03
BIBLIOGRAFIA
1. McKeeman W. M., Comm. ACM, 5, 604, 1962.
2. Lyness Y. N., Y. ACM., 16, 483, 1969.
3. Rice Y. R., Y. ACM, 22, 61, 1975.
4. Malcolm M. A., Simpson R. B. Trans. on Math. Software, 1, 129, 1975.