Sie sind auf Seite 1von 24

10/07/13

Clculo numrico con bc

Clculo numrico con bc


Marc Melndez Schofield
Para la mayor parte de los clculos numricos que se pueden llegar a necesitar en el estudio de una carrera cientfica como ciencias fsicas o matemticas, no es necesario disponer de un ordenador potente, ni de software demasiado avanzado. Este artculo muestra cmo llevar a cabo clculos relativamente interesantes con una simple calculadora de lnea de comandos llamada bc. bc viene instalado con la mayor parte de los sistemas inspirados en Unix (como Linux, FreeBSD, etc.). Tiene la ventaja de ser un programa sencillo y compacto, adems del hecho de que los clculos son interpretados (en otras palabras, no hace falta compilar). Sin embargo, tiene el inconveniente de ser un poco limitado (no se pueden crear matrices bidimensionales, por ejemplo).

Contenidos
1. bc bsico 1.1 Operaciones aritmticas 1.2 Variables 1.3 Funciones matemticas 2. Definicin de funciones 3. Creacin de scripts 3.1 Condiciones 3.2 Bucles 3.2.1 for 3.2.2 while 3.2.3 Advertencia 3.3 Matrices 3.4 Variables auto 3.5 Instruccin read() 3.6 Pasar matrices por referencia 4. Ejemplos 4.1 Matemticas 4.1.1 Teora de nmeros 4.1.2 Probabilidad y estadstica 4.1.3 Clculo 4.1.4 Nmeros complejos 4.1.5 Vectores 4.2 Fsica 4.2.1 Dinmica de una partcula 4.2.2 Campos de fuerzas

1. bc bsico
Para entrar en bc, simplemente ejecuta el comando bc desde la lnea de comandos.

1.1 Operaciones aritmticas


A continuacin, escribe 5+3 y pulsa enter. >b c 5 + 3
marcmmw.freeshell.org/esp/programacion/bc.html 1/24

10/07/13

Clculo numrico con bc

8 La respuesta se muestra en la lnea siguiente. Se pueden utilizar los parntesis para agrupar trminos. ( 5 + 1 0 ) * 2 3 0 5 + 1 0 * 2 2 5 Para calcular una potencia, se utiliza el signo ^. 2 ^ 5 3 2 La divisin puede resultar desconcertante en un primer momento. 7 / 5 1 Esto es debido a que en la solucin se estn ignorando los decimales. Por defecto, obtenemos el cociente entero. El resto de la divisin se puede calcular con el operador %. 7 % 5 2 El nmero de decimales de los clculos se controla con la variable scale. Si queremos dos decimales, s c a l e = 2 7 / 5 1 . 4 0 La raz cuadrada se calcula con la funcin sqrt (del ingls "square root"). s q r t ( 4 ) 2 Para salir del programa, escribe quit y pulsa enter.

1.2 Variables
Vamos a suponer que queremos calcular la solucin del problema siguiente:
Calcular la fuerza elctrica que ejerce una carga de 1 microcoulombio sobre una carga de 2,5 microcoulombios situada en el vaco a 5 centmetros de ella.

Podramos aplicar la ley de Coulomb (F = K(q1q2)/r2), s c a l e = 7 9 * 1 0 ^ 9 * 1 * 1 0 ^ 6 * 2 . 5 * 1 0 ^ 6 / 0 . 0 5 ^ 2 9 . 0 0 0 0 0 0 0


marcmmw.freeshell.org/esp/programacion/bc.html 2/24

10/07/13

Clculo numrico con bc

pero es ms legible definir los valores por separado, y utilizar una expresin simblica (ntese que las variables se representan con letras minsculas). s c a l e=7 k=9 * 1 0 ^ 9 q 1=1 * 1 0 ^ 6 q 2=2 . 5 * 1 0 ^ 6 r=0 . 0 5 k * q 1 * q 2 / r ^ 2 9 . 0 0 0 0 0 0 0 Tambin se podra haber definido la variable f, as: f=k * q 1 * q 2 / r ^ 2 f 9 . 0 0 0 0 0 0 0 Hay que tener cuidado con las expresiones del tipo "3a", que devuelven un mensaje de error. Los productos se deben escribir explcitamente: 3*a. a = 3 3 a ( s t a n d a r d _ i n )2 1 :s y n t a xe r r o r 3 * a 9

1.3 Funciones matemticas


Si, en lugar de ejecutar el comando bc a secas, se utiliza la opcin -l (es decir, escribimos el comando bc -l), bc carga su librera matemtica, que incluye las funciones seno, coseno, arco tangente, logaritmo natural, exponencial y de Bessel. Podemos calcular los logaritmos neperianos de 1 y 2 as: >b cl l ( 1 ) 0 l ( 2 ) . 6 9 3 1 4 7 1 8 0 5 5 9 9 4 5 3 0 9 4 1 Las funciones includas en la librera matemtica son: s(x) Seno de x (x en radianes). c(x) Coseno de x (x en radianes). a(x) Arco tangente de x, (devuelve un valor en radianes). l(x) Logaritmo natural x. e(x) Exponencial de x. j(n,x) Funcin de Bessel de orden n en x.

2. Definicin de funciones
El lector habr notado, quizs, que no se mencion la funcin tangente entre las de la
marcmmw.freeshell.org/esp/programacion/bc.html 3/24

10/07/13

Clculo numrico con bc

librera matemtica de bc. Esto se debe, simplemente, a que bc no incluye esta funcin por defecto. Sin embargo, esto es muy fcil de remediar con conocimientos bsicos de trigonometra. En efecto, podramos calcular la tangente de /4 radianes de la siguiente manera. >b cl p i=3 . 1 4 1 5 9 2 7 ; s ( p i / 4 ) / c ( p i / 4 ) ; 1 . 0 0 0 0 0 0 0 2 3 2 0 5 1 0 3 6 5 0 0 1 q u i t El resultado no es exactamente 1 debido a que slo hemos utilizado siete decimales en la expresin de . Supongamos que queremos calcular la tangente de muchos ngulos diferentes. En este caso, sera mucho ms sencillo tener una funcin tangente (t(x), por ejemplo) en lugar de tener que invocar el cociente entre el seno y el coseno. Podemos definir esta funcin de la manera siguiente: >b cl p i = 3 . 1 4 1 5 9 2 7 ; d e f i n et ( x ){ r e t u r ns ( x ) / c ( x ) ; } t ( p i / 4 ) ; 1 . 0 0 0 0 0 0 0 2 3 2 0 5 1 0 3 6 5 0 0 1 t ( p i / 6 ) ; . 5 7 7 3 5 0 2 7 9 5 0 3 0 0 5 0 9 0 8 9 Hemos creado la funcin t(x) con la instruccin define. Entre llaves, explicamos el efecto de la funcin, que toma un valor (representado por x) y devuelve el seno de este valor dividido por su coseno (s(x)/c(x)). Algunas versiones de bc pueden exigir que lo que sigue al return vaya entre parntesis. Evidentemente, sera mucho ms cmodo poder definir la funcin tangente de una vez por todas. Y por qu limitarnos a la funcin tangente y no incluir tambin el valor de otras funciones, como la secante, o incluso el valor de ? Para ello, escribimos en un archivo de texto las instrucciones siguientes: p i = 3 . 1 4 1 5 9 2 7 ; d e f i n et ( x ){ r e t u r ns ( x ) / c ( x ) ; } d e f i n es e c ( x ) { r e t u r n1 / c ( x ) ; } d e f i n ec o s e c ( x ) { r e t u r n1 / s ( x ) ; } d e f i n ec o t a n ( x ) { r e t u r nc ( x ) / s ( x ) ; } Podemos guardar las lneas precedentes en "trigonometria.bc". Ya no es necesario incluir la
marcmmw.freeshell.org/esp/programacion/bc.html 4/24

10/07/13

Clculo numrico con bc

definicin de una funcin en una sola lnea, y esto hace ms legibles nuestros clculos. Cuando queramos utilizar nuestras definiciones, basta con incluir el nombre de nuestro archivo al invocar bc. Es importante recordar que si estamos ejecutando bc desde un directorio diferente del que contiene nuestro archivo, es necesario incluir tambin la ruta hasta el archivo. >b clt r i g o n o m e t r i a . b c c o s e c ( p i / 6 ) ; 1 . 9 9 9 9 9 9 9 7 3 2 0 5 0 5 5 0 5 1 9 4

3. Creacin de scripts
Hasta ahora, hemos visto cmo definir funciones que utilizaremos ms adelante en nuestros clculos, pero siempre hemos sido nosotros quienes debamos indicar la operacin a llevar a cabo. Esto no es una exigencia de bc. No hay ningn problema si tambin queremos incluir clculos definidos de antemano en nuestros ficheros. Supongamos que necesitamos los cien primeros decimales del nmero . Como sabemos que tg(/4) = 1, podemos deducir que = 4 arctg(1). Recurdese que la funcin arctg(x) se expresa en bc como a(x). En el fichero pi.bc podramos escribir esto: / *L o sc i e np r i m e r o sd e c i m a l e sd ep i* / s c a l e=1 0 0 ; p r i n t" C l c u l od ep ih a s t ae lc e n t s i m od e c i m a l : \ n " ; p r i n t4 * a ( 1 ) ; p r i n t" \ n " ; q u i t ; La expresin entre los signos /* y */ es un comentario, y bc se lo salta al interpretar nuestras instrucciones. Los comentarios se incluyen para que el cdigo sea ms legible, no slo por otros programadores, sino tambin para uno mismo. Un programa complejo sin comentarios se vuelve completamente ilegible en cuanto uno lo ha dejado de lado durante una temporada. Volvamos a nuestro cdigo. La instruccin scale indica que realizaremos clculos de cien decimales. Print muestra un mensaje en pantalla. El signo "\n" indica un retorno, es decir, el texto pasa a la siguiente lnea, y "quit" sale del programa. La instruccin "print 4*a(1);" muestra en pantalla el clculo deseado. Como la funcin arco tangente viene includa en la librera matemtica, es necesario ejecutar el programa con la opcin "-l". >b clp i . b c C l c u l od ep ih a s t ae lc e n t s i m od e c i m a l : 3 . 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2 6 4 3 3 8 3 2 7 9 5 0 2 8 8 4 1 9 7 \ 1 6 9 3 9 9 3 7 5 1 0 5 8 2 0 9 7 4 9 4 4 5 9 2 3 0 7 8 1 6 4 0 6 2 8 6 2 0 8 9 9 \ 8 6 2 8 0 3 4 8 2 5 3 4 2 1 1 7 0 6 7 6

3.1 Condiciones
Vamos a definir una funcin que calcule el factorial de un nmero. El lector recordar que n! (factorial de n, siendo n un nmero natural) se define como
marcmmw.freeshell.org/esp/programacion/bc.html 5/24

10/07/13

Clculo numrico con bc

n! = n(n-1)!
Es decir, el factorial de un nmero es igual a este nmero multiplicado por el factorial de este nmero menos uno. Esto es un ejemplo tpico de definicin recursiva (es decir, que incluye el mismo trmino a definir). Si definimos 0! = 1 (para garantizar que el clculo finalice en algn momento), podemos definir el factorial en bc como sigue: / *F a c t o r i a ld eu nn m e r on a t u r a l * / s c a l e=0 ; d e f i n ef a c t o r i a l ( n ){ i f ( n<0 ) p r i n t" E r r o r :F a c t o r i a ld eu nn m e r on e g a t i v on od e f i n i d o . \ n " ; i f ( n= =0 ) r e t u r n1 ; i f ( n>0 ) r e t u r nn * f a c t o r i a l ( n 1 ) ; } Este cdigo incluye varias condiciones. Si n es negativo, entonces se muestra un mensaje de error. En el caso de que n sea igual a cero, la funcin devuelve 1. Para nmeros naturales positivos, utilizamos la definicin recursiva. Ntese que se utilizan dos signos de igual para expresar la igualdad entre n y cero. El operador = se conoce como operador de asignacin (asigna a una variable un valor). Por ejemplo, "x = 3" asigna a la variable "x" el valor 3. "x == 3" devuelve 1 (verdadero) si "x" es efectivamente igual a 3 y 0 (falso) en caso contrario. >b c a=3 ; a= =3 ; 1 a=2 ; a= =3 ; 0 Supongamos que el cdigo definido ms arriba se ha incluido en el fichero factorial.bc: >b clf a c t o r i a l . b c f a c t o r i a l ( 5 ) ; 1 2 0 f a c t o r i a l ( 2 ) ; E r r o r :F a c t o r i a ld eu nn m e r on e g a t i v on od e f i n i d o . f a c t o r i a l ( 1 2 0 ) ; 6 6 8 9 5 0 2 9 1 3 4 4 9 1 2 7 0 5 7 5 8 8 1 1 8 0 5 4 0 9 0 3 7 2 5 8 6 7 5 2 7 4 6 3 3 3 1 3 8 0 \ 2 9 8 1 0 2 9 5 6 7 1 3 5 2 3 0 1 6 3 3 5 5 7 2 4 4 9 6 2 9 8 9 3 6 6 8 7 4 1 6 5 2 7 1 9 8 4 9 8 1 \ 3 0 8 1 5 7 6 3 7 8 9 3 2 1 4 0 9 0 5 5 2 5 3 4 4 0 8 5 8 9 4 0 8 1 2 1 8 5 9 8 9 8 4 8 1 1 1 4 3 8 \ 9 6 5 0 0 0 5 9 6 4 9 6 0 5 2 1 2 5 6 9 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

3.2 Bucles
3.2.1 for Tambin podramos haber definido la funcin factorial mediante un bucle. n! es el producto
marcmmw.freeshell.org/esp/programacion/bc.html 6/24

10/07/13

Clculo numrico con bc

desde 1 hasta n.

n! = 12(n-1)n
En cdigo: / * F u n c i nf a c t o r i a l( c o nb u c l ef o r )* / s c a l e=0 ; d e f i n ef a c t o r i a l( n ){ r e s u l t a d o=1 ; f o r ( i=1 ;i< =n ;i + + ) r e s u l t a d o* =i ; r e t u r nr e s u l t a d o ; } Este algoritmo es ms lento que el recursivo. Los resultados parciales se guardan en la variable resultado (que empieza valiendo 1). La instruccin for funciona as: f o r ( < i n i c i a l i z a c i n > ; < c o n d i c i n > ; < a c t u a l i z a c i n > ) La inicializacin es una instruccin que se ejecuta antes de que comience el bucle. En nuestro caso, se asigna el valor 1 a la variable i. La condicin se evala en cada repeticin. Si la condicin se cumple (aqu, que i es menor o igual que n) entonces se vuelve a ejecutar la instruccin que sigue al for. La actualizacin se ejecuta despus de cada repeticin. La actualizacin que usamos aqu es i++, que es una manera de aumentar i en una unidad. Es decir, i++ es equivalente a i = i + 1. En cada iteracin (repeticin), se ejecuta el comando r e s u l t a d o* =i ; que es otra forma de escribir r e s u l t a d o=r e s u l t a d o*i ; Finalmente, se devuelve la variable resultado. 3.2.2 while Otra opcin para programar bucles es utilizar un bucle while. Veamos un ejemplo. / * F u n c i nf a c t o r i a l( b u c l ew h i l e ) * / s c a l e=0 ; d e f i n ef a c t o r i a l ( n ){ i=1 ; r e s u l t a d o=1 ; w h i l e( i< =n ) { r e s u l t a d o* =i ; i + + ;
marcmmw.freeshell.org/esp/programacion/bc.html 7/24

10/07/13

Clculo numrico con bc

} r e t u r nr e s u l t a d o ;

Este algoritmo es slo ilustrativo. Desde el punto de vista del clculo de un factorial no es demasiado bueno. Este programa tambin incluye la utilizacin de las llaves para agrupar instrucciones. A continuacin de la instruccin while hay un bloque de instrucciones entre llaves. El comando while se aplica al bloque entero. 3.2.3 Advertencia Con los bucles siempre hay que asegurarse de que la condicin de salida del bucle se cumplir en algn momento. De otra forma, entraremos en un bucle infinito. Por ejemplo, la siguiente funcin se ejecuta indefinidamente. / * B u c l ei n f i n i t o * / d e f i n eb u c l e i n f i n i t o ( x ){ w h i l e ( 1 < 2 ) { p r i n tx + + ; p r i n t" : S o c o r r o !E s t o ye nu nb u c l ei n f i n i t o . \ n " ; } } Para salir de un bucle infinito mientras se est ejecutando pulsa CTRL+C.

3.3 Matrices
bc permite definir matrices de una dimensin. El ndice de cada elemento se encierra entre parntesis. Podemos definir el vector v = (1, -1, 2) y calcular su mdulo as: s c a l e=5 ; v [ 1 ]=1;v [ 2 ]=1 ;v [ 3 ]=2 ; s q r t ( v [ 1 ] ^ 2+v [ 2 ] ^ 2+v [ 3 ] ^ 2 ) ; 2 . 4 4 9 4 8 Una funcin puede aceptar una matriz como argumento. Veremos un ejemplo en el que definimos el sumatorio de los n primeros elementos almacenados en una matriz. d e f i n es u m a t o r i o ( x [ ] ,n ){ s u m a=0 ; f o r ( i=1 ;i< =n ;i + + ) s u m a+ =x [ i ] ; r e t u r ns u m a ; } Los corchetes en x[] indican que la variable x es una matriz. suma += x[i] es equivalente a escribir suma = suma + x[i]. Ntese que se recorren los ndices de la matriz x con la variable i (que cambia en cada iteracin del bucle). Sigue un ejemplo de utilizacin de la funcin sumatorio. u [ 1 ]=1 ;u [ 2 ]=5 ;u [ 3 ]=7 ;u [ 4 ]=5 ;
marcmmw.freeshell.org/esp/programacion/bc.html 8/24

10/07/13

Clculo numrico con bc

s u m a t o r i o ( u [ ] ,4 ) ; 1 8 s u m a t o r i o ( u [ ] ,2 ) ; 6

3.4 Variables auto


Supongamos que tenemos una funcin contar(n) que muestra en pantalla los nmeros desde 1 hasta n. d e f i n ec o n t a r ( n ){ f o r ( i=0 ;i< =n ;i + + ) p r i n ti ,"" ; p r i n t" \ n " ; } Esta funcin no devuelve explcitamente ningn valor (ntese la ausencia de la instruccin return). bc presupone en estos casos que el valor devuelto es cero. Al invocar la rutina, se mostrar este valor nulo en la pantalla. c o n t a r ( 5 ) ; 12345 0 Para evitar este cero no deseado, podemos asignar el valor devuelto a una variable. bc permite asignar valores al punto (.), que no suele usarse como nombre de variable. .=c o n t a r ( 5 ) ; 12345 Imaginemos que queremos utilizar nuestra funcin para mostrar nmeros dispuestos as: 1 12 123 1234 12345 Si escribimos esto, f o r ( i=0 ;i< =5 ;i + + ) .=c o n t a r ( i ) ; obtenemos el resultado siguiente: 1 123 12345 Dnde estn las dos lneas que faltan? El problema aqu es que la funcin contar(n) tambin cambia el valor de la variable i.
marcmmw.freeshell.org/esp/programacion/bc.html 9/24

10/07/13

Clculo numrico con bc

La solucin, dir el lector, es utilizar una variable distinta para cada bucle. Y tiene razn, pero hay un problema. Puede que contar(n) la haya escrito una persona y que la est utilizando otra, que no tiene por qu saber los nombres de las variables que usa esta funcin. Para usarla, debera bastar con saber qu hace, sin tener que consultar cmo lo hace. bc permite usar la instruccin auto para especificar que una variable es propia de una funcin. d e f i n ec o n t a r ( n ){ a u t oi ; f o r ( i=0 ;i< =n ;i + + ) p r i n ti ,"" ; p r i n t" \ n " ; } De este modo, bc sabe que la "i" utilizada dentro de contar es diferente de cualquier otra que se haya podido utilizar en el programa. Este bloque termina con una advertencia importante. Si la funcin contar invocara a otra funcin que utilizara la variable i (y que no tuviera instruccin auto), entonces la variable modificada sera la de contar(n), y no la de otras partes del programa. Es decir, las variables auto forman una jerarqua. Si en una funcin f no se declara que una variable es auto, entonces la variable a la que nos referimos es la de la funcin que invoc a f (que a su vez puede ser la de la funcin que invoc a esta, y as sucesivamente hasta que encontremos una declaracin auto, o ninguna, en caso de que siempre nos estemos refiriendo a la misma variable).

3.5 Instruccin read()


En algunas ocasiones, puede resultar conveniente que ciertos datos se introduzcan durante la ejecucin de la funcin. Para ello, se utiliza la instruccin read(). d e f i n ep i ( ){ a u t os ,n ,p i ; s=s c a l e ; p r i n t" D e c i m a l e sd ep i : \ n " ; n=r e a d ( ) ; s c a l e=n ; p i=4 * a ( 1 ) ; s c a l e=s ; r e t u r np i ; } Al invocar la funcin pi() obtenemos lo siguiente (los valores 10 y 20 los introduce el usuario): p i ( ) ; D e c i m a l e sd ep i : 1 0 3 . 1 4 1 5 9 2 6 5 3 2 p i ( ) ; D e c i m a l e sd ep i : 2 0 3 . 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 4

3.6 Pasar matrices por referencia


marcmmw.freeshell.org/esp/programacion/bc.html 10/24

10/07/13

Clculo numrico con bc

Puede que necesites que una funcin cambie el valor de uno de sus argumentos. Por ejemplo, si tenemos una matriz que guarda los datos de una hora (horas, minutos y segundos) y queremos aadir h horas, m minutos y s segundos, podemos usar la funcin siguiente: d e f i n es u m a h o r a s ( * h o r a [ ] ,h ,m ,s ){ s=s c a l e ; s c a l e=0 ; h o r a [ 1 ]=h o r a [ 1 ]+h+( h o r a [ 2 ]+m ) / 6 0+( h o r a [ 3 ]+s ) / 3 6 0 0 ; h o r a [ 2 ]=( h o r a [ 2 ]+m+( h o r a [ 3 ]+s ) / 6 0 ) % 6 0 ; h o r a [ 3 ]=( h o r a [ 3 ]+s ) % 6 0 ; s c a l e=s ; } El asterisco delante de la matriz hora[] en la primera lnea de la definicin indica que la matriz se pasa por referencia. Si no se incluye este asterisco, la funcin no modifica la matriz hora[], sino una copia local de estas variables. El resultado es ste: / *H o r ao r i g i n a l :1 : 2 0 : 4 5* / m i h o r a [ 1 ]=1 ;m i h o r a [ 2 ]=2 0 ;m i h o r a [ 3 ]=4 5 ; / *S u m a2h o r a s ,4 5m i n u t o sy2 0s e g u n d o s* / .=s u m a h o r a s ( m i h o r a [ ] ,2 ,4 5 ,2 0 ) ; / *R e s u l t a d o* / p r i n tm i h o r a [ 1 ] ," : " ,m i h o r a [ 2 ] ," : " ,m i h o r a [ 3 ] ," \ n " ; 4 : 6 : 5 Si no hubiramos pasado la matriz mihora[] por referencia, nos habramos encontrado que el resultado era 1:20:45.

4. Ejemplos
El cdigo de los ejemplos que siguen debera poder consultarse en mi espacio gopher, junto a este archivo. (gopher://sdf.lonestar.org/1/users/marcmmw/esp/programacion) En esta versin (html), he includo un enlace directo a cada uno de los ficheros. Los usuarios de Firefox deberan poder acceder sin problemas utilizando el complemento Overbite. Los usuarios de Internet explorer pueden descargar Firefox gratuitamente en la pgina oficial de firefox.

4.1 Matemticas
En los siguientes ejemplos, se comentan slo fragmentos de cdigo. Con el signo [...] se indica la omisin de alguna parte del programa. 4.1.1 Teora de nmeros (numeros.bc) Nuestro ejemplo incluye un algoritmo para encontrar los factores primos de un nmero natural n. No es el algoritmo ms eficiente, pero es uno de los ms sencillos de comprender.
marcmmw.freeshell.org/esp/programacion/bc.html 11/24

10/07/13

Clculo numrico con bc

Para cada nmero i menor que n, comprobamos si n es divisible entre i, es decir, si el resto de n entre i es cero. Si es as, realizamos la divisin y factorizamos el cociente. Con este mtodo, slo es necesario que i recorra los nmeros desde 2 hasta la raz cuadrada de n (el lector puede entretenerse en demostrar esto). / *F a c t o r e sp r i m o s* / d e f i n ef a c t o r e s ( n ){ [ . . . ] i f ( n> =2 ) { m=n ; i=2 ; w h i l e ( i< =s q r t ( n ) ) { i f ( ( m%i )= =0 ) { [ . . . ] p r i n t i ; m=m/i ; i=i-1 ; } i=i+1 ; }

} [ . . . ]

El fichero contiene tambin funciones que calculan los n-simos nmeros de Mersenne y de Fermat. >b cln u m e r o s . b c f a c t o r e s ( 1 2 5 4 ) ; 2 ,3 ,1 1 ,1 9 . 1 2 5 4 m e r s e n n e ( 1 2 ) ; 4 0 9 5 f e r m a t ( 5 ) ; 6 5 5 3 7 f a c t o r e s ( f e r m a t ( 4 ) ) ; 6 5 5 3 7 . 6 5 5 3 7 f a c t o r e s ( m e r s e n n e ( 1 2 ) ) ; 3 ,3 ,5 ,7 ,1 3 . 4 0 9 5 Tambin se puede utilizar la funcin comb(n,m) para calcular nmeros combinatorios (coeficientes binomiales). El tringulo de Tartaglia (tambin conocido como tringulo de Pascal) se consigue ordenando los coeficientes binomiales por filas, de modo que cada nmero es igual a la suma de los dos nmeros ms cercanos en la fila inmediatamente superior. 11
marcmmw.freeshell.org/esp/programacion/bc.html 12/24

10/07/13

Clculo numrico con bc

121 1331 14641 e t c . Mediante comb(n,m) es muy sencillo calcular los coeficientes del tringulo por filas, como veremos a continuacin. Mediante un bucle (en i) se recorren las filas del tringulo. En cada iteracin de este bucle, se ejecuta otro bucle (en j) que comienza en 0 y acaba en el valor que toma i en la iteracin, para recorrer todos los elementos de la fila. Se muestra cada elemento en pantalla (separndolo del anterior con un espacio). Ntese que antes se ha introducido un bucle en j para imprimir un nmero adecuado de espacios antes de los elementos de una fila para crear el hueco a la izquierda del tringulo. >b clp r o b a b i l i d a d . b c s c a l e=0 ; f o r ( i=1 ;i< =9 ;i + + ) { / *D e j ah u e c oal ai z q u i e r d ad el af i l a* / f o r ( j=1 ;j< =9-i ;j + + ) p r i n t"" ; / *M u e s t r ae np a n t a l l al o sc o e f i c i e n t e s* / f o r ( j=0 ;j< =i ;j + + ) p r i n tc o m b ( i , j ) ,"" ; / *P a s aal al n e as i g u i e n t e* / p r i n t" \ n " ; } 11 121 1331 14641 151 01 051 161 52 01 561 172 13 53 52 171 182 85 67 05 62 881 193 68 41 2 61 2 68 43 691 El clculo est resuelto, pero la alineacin todava no es perfecta. El lector ambicioso querr, quizs, ensayar soluciones ms sofisticadas. Leo en la wikipedia que si se marcan los nmeros impares del tringulo de Tartaglia, se obtiene una figura parecida al tringulo de Sierpinski. Vamos a comprobarlo cambiando el segundo bucle en j del cdigo anterior por las lneas siguientes. f o r ( j=0 ;j< =i ;j + + ) { i f ( c o m b ( i , j ) % 2 = = 1 )p r i n t" X" ; i f ( c o m b ( i , j ) % 2 = = 0 )p r i n t" " ; } En la prueba que hice yo, dibuj las primeras quince filas (en lugar de nueve) y empec en i = 0. El resultado es un dibujo como el que se muestra a continuacin. X XX X X XXXX
marcmmw.freeshell.org/esp/programacion/bc.html 13/24

10/07/13

Clculo numrico con bc

X X XX XX X X X X XXXXXXXX X X XX XX X X X X XXXX XXXX X X X X XX XX XX XX X X X X X X X X XXXXXXXXXXXXXXXX Con ms lneas el parecido es todava ms evidente. 4.1.2 Probabilidad y estadstica (probabilidad.bc) Las funciones de densidad de probabilidad dependen de la librera matemtica. En probabilidad.bc se definen funciones para calcular la media aritmtica y la desviacin estndar de n datos almacenados en una matriz. >b clp r o b a b i l i d a d . b c s c a l e=2 ; x [ 1 ]=2 ;x [ 2 ]=4 ;x [ 3 ]=4 ;x [ 4 ]=4 ; x [ 5 ]=5 ;x [ 6 ]=5 ;x [ 7 ]=7 ;x [ 8 ]=9 ; m e d i a ( x [ ] ,8 ) ; 5 . 0 0 d e s v ( x [ ] ,8 ) ; 2 . 0 0 Qu ms incluye el fichero probabilidad.bc? Adems de las funciones factorial y comb(n,m), se encuentran definidas las funciones binomial, normal y de Poisson utilizadas en probabilidad y estadstica. Con la funcin norm(x, mu, sigma) se obtuvieron los datos para crear la grfica de la funcin normal con mu = 0 y sigma = 1 (ver figura 1). Para crear un grfico como este es necesario, en primer lugar, calcular los datos (en nuestro caso, con bc). A continuacin se utiliza un programa de dibujo (la figura 1 se cre con graph, incluido en los plotutils). Para el primer paso, se calculan los valores de muchas parejas de valores (x, f(x)). Por ejemplo, se pueden escribir las siguientes lneas en un fichero normal.bc:
Figura 1: Distribucin normal con = 0 y = 1.

s c a l e=1 0 ; f o r ( x=2 ;x< =2 ;x+ =0 . 0 5 ) p r i n tx ," " ,n o r m ( x , 0 , 1 ) ," \ n " ;


marcmmw.freeshell.org/esp/programacion/bc.html 14/24

10/07/13

Clculo numrico con bc

q u i t La rutina anterior calcula el valor de la funcin norm para valores de x entre -2 y 2 separados por intervalos de 0.05. Ejecutando esta rutina junto con el contenido de probabilidad.bc obtenemos los datos. >b clp r o b a b i l i d a d . b cn o r m a l . b c 2 . 0 5 3 9 9 0 9 6 6 4 1 . 9 5 . 0 5 9 5 9 4 7 0 6 0 1 . 9 0 . 0 6 5 6 1 5 8 1 4 7 [ . . . ] 1 . 9 0 1 . 9 5 2 . 0 0 . 0 6 5 6 1 5 8 1 4 7 . 0 5 9 5 9 4 7 0 6 0 . 0 5 3 9 9 0 9 6 6 4

Se podran copiar todos estos datos a mano, o cortando y pegando, pero es mucho ms cmodo redirigirlos a un fichero (aqu normal.dat) directamente desde la lnea de comandos as: >b clp r o b a b i l i d a d . b cn o r m a l . b c>n o r m a l . d a t En lugar de mostrar los datos en pantalla, la instruccin "> normal.dat" indica que los datos deben guardarse en el fichero nombrado. Ahora queremos crear una imagen a partir de estos datos con el programa graph. >g r a p hTg i fy01n o r m a l . d a t>n o r m a l . g i f Con "-T gif" se especifica el formato de la imagen. "-y 0 1" indica el rango de valores del eje y. Si se instala plotutils, se suelen instalar tambin las pginas de manual correspondientes, por lo que pueden consultarse ah ms opciones del comando graph. La pgina del manual se invoca as: >m a ng r a p h Pueden conseguirse los mismos resultados de manera ms sencilla con programas como gnuplot, pero uno de los objetivos de este artculo es el de mostrar cmo se pueden realizar clculos relativamente sofisticados con recursos muy limitados. 4.1.3 Clculo (calculo.bc) Este apartado est dedicado a la derivacin e integracin numrica, pero comentaremos antes el clculo numrico de lmites. En los casos en los que no existe indeterminacin, basta con sustituir el valor correspondiente. Para calcular el lmite s i n ( x ) l i m x>2 2L n ( x ) no hay ms que escribir
marcmmw.freeshell.org/esp/programacion/bc.html 15/24

10/07/13

Clculo numrico con bc

>b cl s ( 2 ) / ( 2 * l ( 2 ) ) El problema surge con los lmites en el infinito y las indeterminaciones. Veamos el lmite de sin(x)/x en x = 0. >b cl s ( 0 ) / 0 R u n t i m ee r r o r( f u n c = ( m a i n ) ,a d r = 7 ) :D i v i d eb yz e r o La idea intuitiva que hay detrs de la definicin matemtica de lmite de una funcin en un punto es sta: a medida que la variable se aproxima al punto considerado, el valor de la funcin se aproxima inexorablemente al lmite (si es que existe). Por lo tanto, podemos examinar el comportamiento de la funcin en las cercanas del punto. >b cl s ( 0 . 1 ) / 0 . 1 . 9 9 8 3 3 4 1 6 6 4 6 8 2 8 1 5 2 3 0 0 s ( 0 . 0 1 ) / 0 . 0 1 . 9 9 9 9 8 3 3 3 3 4 1 6 6 6 6 4 6 8 0 0 s ( 0 . 0 0 1 ) / 0 . 0 0 1 . 9 9 9 9 9 9 8 3 3 3 3 3 3 4 1 6 6 0 0 0 El lmite en este caso parece ser igual a uno (y, de hecho, lo es). Para los lmites en el infinito, podemos utilizar valores grandes en valor absoluto. >b cl e ( 1 0 ) . 0 0 0 0 4 5 3 9 9 9 2 9 7 6 2 4 8 4 8 5 e ( 2 0 ) . 0 0 0 0 0 0 0 0 2 0 6 1 1 5 3 6 2 2 4 3 e ( 5 0 ) 0 Evidentemente, lo que cuenta como nmero "grande" depende del contexto. En cualquier caso, podramos preguntar qu garanta tenemos de que la funcin vaya a respetar la tendencia observada para entornos ms reducidos (o nmeros mayores). La respuesta es que, sin una demostracin rigurosa, no hay garanta, y es importante tener en cuenta este hecho en la derivacin e integracin numricas (cuyas definiciones estn basadas, al fin y al cabo, en la de lmite). El lector puede entretenerse en intentar determinar (sin xito) el lmite de sin(1/x) cuando x tiende a cero, por el mtodo indicado. Sin embargo, si las funciones tienen un comportamiento suficientemente parecido al de una recta en los intervalos considerados, es fcil definir una aproximacin numrica para sus derivadas e integrales. La definicin de derivada es: f ( a+h )-f ( a ) f ' ( a )=l i m h>0 h Para conseguir una aproximacin, bastar con calcular el cociente sustituyendo h por un valor p suficientemente pequeo. Por ejemplo, la derivada de sin(x) en x = 0 se puede
marcmmw.freeshell.org/esp/programacion/bc.html 16/24

10/07/13

Clculo numrico con bc

aproximar as: >b cl ( s ( 0+0 . 0 1 )-s ( 0 ) ) / 0 . 0 1 . 9 9 9 9 8 3 3 3 3 4 1 6 6 6 6 4 6 8 0 0 Como siempre, nos gustara tener una funcin que tome la funcin a derivar, el punto, y el paso p. Pero en bc no se pueden pasar las funciones como parmetros, es decir, no se puede definir una funcin derivada(f(x), x, p), siendo f otra funcin. Afortunadamente, podemos resolver este problema dando un pequeo rodeo. d e f i n ed e r i v a d a ( a , p ){ r e t u r n( f ( a + p )-f ( a ) ) / p ; } En calculo.bc la funcin derivada asume que la funcin a derivar se llama f(x), por lo que slo hay que definirla antes de invocar la rutina. >b clc a l c u l o . b c p i=3 . 1 4 1 5 9 2 7 ; / * A h o r al af u n c i nad e r i v a re ss i n ( x ) * / d e f i n ef ( x ){r e t u r ns ( x ) ; } d e r i v a d a ( p i / 6 , 0 . 0 0 0 1 ) ; . 8 6 6 0 0 1 0 0 0 0 / * A h o r al af u n c i nad e r i v a re sc o s ( x ) * / d e f i n ef ( x ){r e t u r nc ( x ) ; } d e r i v a d a ( p i / 6 , 0 . 0 0 0 1 ) ; . 5 0 0 0 4 3 0 0 0 0

Figura 2: Funcin de Bessel de orden 3 (en rojo) y su derivada (en azul). Datos calculados con bc y dibujados con graph.

En nuestro fichero hemos incluido tambin la derivada ensima por medio de una definicin recursiva. Podemos utilizar nuestra rutina para calcular derivadas laterales, lo cual es especialmente til en funciones definidas por intervalos. >b clc a l c u l o . b c d e f i n ef ( x ){
marcmmw.freeshell.org/esp/programacion/bc.html 17/24

10/07/13

Clculo numrico con bc

i f ( x< =0 )r e t u r nx ^ 2 ; i f ( x>0 )r e t u r nx ; } / *D e r i v a d ad ef ( x )e nc e r op o rl ad e r e c h a* / d e r i v a d a ( 0 ,0 . 0 0 1 ) ; 1 . 0 0 0 0 0 0 0 0 0 0 / *D e r i v a d ad ef ( x )e nc e r op o rl ai z q u i e r d a* / d e r i v a d a ( 0 ,0 . 0 0 1 ) ; . 0 0 1 0 0 0 0 0 0 0 Para calcular las integrales, utilizaremos la definicin de Riemann. /b _ _N | f ( x )d x=l i m > f ( x)h /a h>0 ~ ~ i=0 i Donde N = (a + b)/h. De nuevo, aproximamos el lmite sustituyendo h por un valor pequeo p y obteniendo un sumatorio finito. d e f i n ei n t e g r a l ( a ,b ,p ){ i n t e g=0 ; f o r ( x=a ;x<b ;x+ =p ) i n t e g+ =f ( x ) * p ; r e t u r ni n t e g ; } Para calcular la integral definida de la funcin cos(x) entre /2 y : >b clc a l c u l o . b c p i=3 . 1 4 1 5 9 2 7 ; d e f i n ef ( x ){r e t u r nc ( x ) ; } i n t e g r a l ( p i / 2 ,p i ,0 . 0 1 ) ; 1 . 0 0 4 1 9 5 3 6 0 0 Para conseguir una aproximacin mayor se puede utilizar un paso menor, pero hay ocasiones en que es conveniente utilizar un nmero ms reducido de pasos (por ejemplo, cuando el tiempo que lleva evaluar la funcin f(x) es elevado). Nuestra aproximacin meda el rea bajo la curva f(x) con rectngulos, pero podemos cambiar el borde superior de nuestros rectngulos para que se ajuste ms a la curva f(x) como, por ejemplo, si utilizamos una recta desde el punto (x, f(x)) al punto (x + h, f(x + h)). Hemos introducido una aproximacin todava mejor mediante tramos parablicos atribuida a Thomas Simpson. >b clc a l c u l o . b c s c a l e=2 0 ; p i=4 * a ( 1 ) ; d e f i n ef ( x ){r e t u r ns ( x ) ; } i n t e g r a l ( 0 ,2 * p i ,0 . 1 ) ; . 0 0 0 6 9 9 4 4 9 2 3 0 2 8 4 9 6 9 0 6 s i m p s o n ( 0 ,2 * p i ,0 . 1 ) ; . 0 0 0 1 4 1 3 6 3 6 2 1 4 9 4 7 7 7 8 4 4.1.4 Nmeros complejos (complejos.bc)
marcmmw.freeshell.org/esp/programacion/bc.html 18/24

10/07/13

Clculo numrico con bc

En este apartado se ponen de manifiesto algunas de las limitaciones de bc. Las funciones no pueden devolver matrices (es decir, no es vlida la instruccin return z[];), as que hay que buscar algn sistema alternativo. Representaremos los nmeros complejos con una matriz de dos elementos, de modo que si z = a + bi, usaremos las asignaciones siguientes: z [ 0 ]=a ; z [ 1 ]=b ; Algunas funciones devuelven un nmero real (parte real, parte imaginaria, mdulo y argumento), mientras que otras deberan devolver un nmero complejo (exponencial de un nmero complejo, por ejemplo). En estos ltimos casos, pasaremos por referencia la matriz donde queremos que se almacene la accin de la funcin, mientras que la funcin devolver el valor cero. En nuestro ejemplo, definiremos dos nmeros complejos z1 = 3 + 2i, y z2 = -1 + i. Podemos mostrarlos en forma de binomio con la rutina printz(z[]). z 1 [ 0 ]=3 ;z 1 [ 1 ]=2 ; z 2 [ 0 ]=1 ;z 2 [ 1 ]=1 ; .=p r i n t z ( z 1 [ ] ) ; 3+2 i .=p r i n t z ( z 2 [ ] ) ; 1+1 i Asignamos el valor de la funcin print z a la variable "." para evitar que se muestre en pantalla un cero adicional (ver seccin 3.4). A continuacin, Al sumar, restar, multiplicar o dividir z1 y z2, guardamos el resultado la variable zres[]. .=s u m a z ( z 1 [ ] ,z 2 [ ] ,z r e s [ ] ) ;.=p r i n t z ( z r e s [ ] ) ; 2+3 i .=r e s t a z ( z 1 [ ] ,z 2 [ ] ,z r e s [ ] ) ;.=p r i n t z ( z r e s [ ] ) ; 4+1 i .=p r o d z ( z 1 [ ] ,z 2 [ ] ,z r e s [ ] ) ;.=p r i n t z ( z r e s [ ] ) ; 5+1 i s c a l e=2 ; .=d i v z ( z 1 [ ] ,z 2 [ ] ,z r e s [ ] ) ;.=p r i n t z ( z r e s [ ] ) ; 0 . 5 0+2 . 5 0 i Podemos calcular la parte real, imaginaria, mdulo y argumento. La funcin printzt(z[]) escribe z en forma trigonomtrica. r e z ( z 1 [ ] ) ; 3 i m z ( z 1 [ ] ) ; 2 m o d z ( z 1 [ ] ) ; 3 . 6 0 a r g z ( z 1 [ ] ) ;
marcmmw.freeshell.org/esp/programacion/bc.html 19/24

Figura 3: Fractal de Mandelbrot y detalle del mismo (derecha). Los clculos se realizaron en bc con las rutinas de complejos.bc.

10/07/13

Clculo numrico con bc

. 5 8 .=p r i n t z t ( z 1 [ ] ) ; 3 . 6 0*( c o s ( . 5 8 )+is i n ( . 5 8 ) ) Las potencias en bc slo aceptan exponentes enteros, as que he definido una funcin pot(x, y) para exponentes reales arbitrarios. Utilizando esta expresin, he escrito otra llamada potz que calcula el resultado de elevar un nmero complejo a un nmero real arbitrario. pot(x,y) utiliza el operador ^ cuando y es entero, y la expresin

xy = ey Ln(x)
para cualquier otro nmero real. s c a l e=5 ; / * C l c u l od e3 ^ 2 . 1 * / p o t ( 3 , 2 . 1 ) ; 1 0 . 0 4 5 0 5 / * C l c u l od ez 1 ^ 2 . 1 * / .=p o t z ( z 1 [ ] ,2 . 1 ,z r e s [ ] ) ;.=p r i n t z ( z r e s [ ] ) ; 4 . 8 7 2 9 4+1 3 . 9 5 2 0 2 i Se puede calcular una raz de orden n utilizando potz para hallar la potencia 1/n. El resto de las races se pueden ir calculando multiplicando este resultado por e2ki/n, con k = 1, 2, ..., n - 1. La funcin raices(z[],n) muestra n races de z[]. z [ 0 ]=1 ;z [ 1 ]=0 ; / * R a zo c t a v ad e1 * / .=p o t z ( z [ ] ,1 / 8 ,z r e s [ ] ) ;.=p r i n t z ( z [ ] ) ; 1+0 i / * O c h or a c e so c t a v a sd e1 * / .=r a i c e s z ( z [ ] ,8 ) ; 1 . 0 0 0 0 0+0 i . 7 0 7 1 1+. 7 0 7 1 0 i 0+1 . 0 0 0 0 0 i . 7 0 7 1 0+. 7 0 7 1 0 i . 9 9 9 9 9+0 i . 7 0 7 1 0+. 7 0 7 1 0 i 0+1 . 0 0 0 0 0 i . 7 0 7 1 0+. 7 0 7 1 1 i El fichero incluye tambin funciones para calcular exponenciales, senos, cosenos y logaritmos de nmeros complejos. Como el logaritmo es una funcin multivaluada, logz(z[], zres[]) almacena en zres[] solamente uno de los valores posibles. Los dems pueden hallarse sumando 2ki a este valor (donde k es un nmero entero). Por ltimo, la funcin potzz(z1[],z2[], zres[]) calcula el resultado de z1z2. .=e x p z ( z 1 [ ] ,z r e s [ ] ) ;.=p r i n t z ( z r e s [ ] ) ; 8 . 3 5 8 3 9+1 8 . 2 6 3 5 7 i .=s i n z ( z 1 [ ] ,z r e s [ ] ) ;.=p r i n t z ( z r e s [ ] ) ; . 5 3 0 8 7+3 . 5 9 0 5 5 i .=c o s z ( z 1 [ ] ,z r e s [ ] ) ;.=p r i n t z ( z r e s [ ] ) ; 3 . 7 2 4 5 2+. 5 1 1 7 8 i .=l o g z ( z 1 [ ] ,z r e s [ ] ) ;.=p r i n t z ( z r e s [ ] ) ; 1 . 2 8 2 4 7+. 5 8 7 9 9 i
marcmmw.freeshell.org/esp/programacion/bc.html 20/24

10/07/13

Clculo numrico con bc

.=p o t z z ( z 1 [ ] ,z 2 [ ] ,z r e s [ ] ) ;.=p r i n t z ( z r e s [ ] ) ; . 2 2 9 5 0+3 . 6 5 8 3 6 i 4.1.5 Vectores (vectores.bc) Utilizando ideas parecidas a las de la seccin anterior, se pueden definir las operaciones vectoriales. Las funciones que devuelvan un vector almacenarn su resultado en la variable vres[]. La funcin printv(v[]) muestra el vector v[] con sus coordenadas listadas entre parntesis. Las funciones estn definidas para vectores tetradimensionales, pero se pueden utilizar para vectores en dos y tres dimensiones dejando las componentes adicionales iguales a cero: v [ 1 ]=1 ;v [ 2 ]=1 ; Con este comando se define el vector v = (1, -1). bc supone automticamente que v[0] y v[3] son nulos (siempre que no se les haya asignado antes un valor diferente). Definiremos los vectores v 1 = (0, 2, -1, 2), v 2 = (-1, 1, 0, 3) y v 3 = (0, 0, 2, -1). v 1 [ 0 ]=0 ;v 1 [ 1 ]=2 ;v 1 [ 2 ]=1 ;v 1 [ 3 ]=2 ; v 2 [ 0 ]=1 ;v 2 [ 1 ]=1 ;v 2 [ 2 ]=0 ;v 2 [ 3 ]=3 ; v 3 [ 0 ]=0 ;v 3 [ 1 ]=0 ;v 3 [ 2 ]=2 ;v 3 [ 3 ]=1 ; .=p r i n t v ( v 1 [ ] ) ;.=p r i n t v ( v 2 [ ] ) ;.=p r i n t v ( v 3 [ ] ) ; ( 0 ,2 ,1 ,2 ) ( 1 ,1 ,0 ,3 ) ( 0 ,0 ,2 ,1 ) A continuacin se muestran ejemplos de las operaciones de suma, resta y producto por un escalar. / *S u m ad ev e c t o r e s* / .=s u m a v ( v 1 [ ] ,v 2 [ ] ,v r e s [ ] ) ;.=p r i n t v ( v r e s [ ] ) ; ( 1 ,3 ,1 ,5 ) / *R e s t ad ev e c t o r e s* / .=r e s t a v ( v 1 [ ] ,v 2 [ ] ,v r e s [ ] ) ;.=p r i n t v ( v r e s [ ] ) ; ( 1 ,1 ,1 ,1 ) / *P r o d u c t op o ru ne s c a l a r* / .=p r o d v ( 3 ,v 1 [ ] ,v r e s [ ] ) ;.=p r i n t v ( v r e s [ ] ) ; ( 0 ,6 ,3 ,6 ) Sigue un ejemplo de los productos internos. El producto escalar y el producto mixto devuelven un nmero real, por lo que no es necesario consultar el valor de vres[] despus de invocar estas funciones. El producto vectorial y el producto mixto estn definidos para vectores tridimensionales, por lo que no entra en el clculo la primera componente de los vectores (la de ndice 0). / *P r o d u c t oe s c a l a r* / e s c a l a r ( v 1 [ ] ,v 2 [ ] ) ; 8 / *P r o d u c t ov e c t o r i a l( P a r av e c t o r e st r i d i m e n s i o n a l e s )* / .=v e c t o r i a l ( v 1 [ ] ,v 3 [ ] ,v r e s [ ] ) ;.=p r i n t v ( v r e s [ ] ) ; ( 0 ,3 ,2 ,4 ) / *P r o d u c t om i x t o( P a r av e c t o r e st r i d i m e n s i o n a l e s )* / m i x t o ( v 1 [ ] ,v r e s [ ] ,v 3 [ ] )
marcmmw.freeshell.org/esp/programacion/bc.html 21/24

10/07/13

Clculo numrico con bc

1 3

4.2 Fsica
Es relativamente comn encontrarse en fsica con una ecuacin intratable desde el punto de vista analtico. En estos casos, no queda ms remedio que recurrir a una solucin numrica. 4.2.1 Dinmica de una partcula (fuerzas.bc) La idea bsica para resolver las ecuaciones del movimiento de una partcula sometida a fuerzas es sencilla. Se parte de las ecuaciones de Newton,

F = m a,
y despejando la aceleracin,

a = d r/dt2 = F/m.
Las derivadas se calculan de forma aproximada utilizando incrementos temporales pequeos (en lugar de resolver el lmite de la definicin). d f f ( t+h )-f ( t ) ~ f ( t+d t )-f ( t ) -=l i m - = , d t h>0 h d t donde dt no es ms que un paso temporal pequeo. Despejando de la frmula de la derivada, se encuentra que, si conocemos las posiciones y velocidades iniciales y las fuerzas, podemos calcular las posiciones y velocidades nuevas despus de un intervalo de tiempo dt.

v(t + dt) =v(t) + a(t)*dt, r(t + dt) = r(t) + v(t)*dt,


Ahora, con las posiciones nuevas, se pueden calcular de nuevo las fuerzas. Repitiendo este proceso, se puede ir avanzando paso a paso en el tiempo calculando la trayectoria de la partcula. En la figura 4, se puede ver la trayectoria tridimensional de una masa lanzada en un campo gravitatorio, un problema clsico de fsica de bachillerato. El cdigo bc no es difcil de entender. Simplemente define los parmetros de la simulacin: posiciones y velocidades iniciales, tiempos iniciales y finales, paso temporal y constantes (aceleracin de la gravedad, masa y carga). A continuacin define la funcin aceleraciones, que utiliza la segunda ley de Newton para calcular las aceleraciones a partir de las fuerzas. En general, la fuerza ser una funcin de la posicin, la velocidad, la masa y la carga. Por ltimo, la funcin
marcmmw.freeshell.org/esp/programacion/bc.html

Figura 4: Trayectoria de una partcula calculada con fuerzas.bc.


22/24

10/07/13

Clculo numrico con bc

integra_ec integra las ecuaciones del movimiento utilizando el mtodo de pasos temporales pequeos explicado antes y produce una lista de datos por columnas. La primera columna presenta el instante temporal y las otras tres las coordenadas rx, ry y rz . Utilizando esta lista, se represent la trayectoria de la figura 4 con el programa gnuplot. Es muy fcil modificar el comportamiento de fuerzas.bc para simular otro tipo de fenmenos. Supongamos que queremos simular el movimiento de un oscilador amortiguado. En este caso, la segunda ley de Newton es

a = d x/dt2 = (k/m) x (c/m) dx/dt.


As que, aparte de los cambios apropiados en las condiciones iniciales, tenemos que convertir la funcin aceleraciones en sta: d e f i n ea c e l e r a c i o n e s ( r [ ] ,v [ ] ,* a [ ] ,m a s a ,c a r g a ){ a [ 1 ]=( k / m ) * r [ 1 ]( c / m ) * v [ 1 ] ; a [ 2 ]=0 ; a [ 3 ]=0 ; } r e t u r n0 ;

Evidentemente, tambin habr que especificar los valores de las constantes nuevas k y c. En la figura 5, se puede ver la grfica de x frente a t para un oscilador amortiguado con los siguientes valores iniciales y constantes k y c:

rx = 1, ry = rz = 0, vx = vy = vz = 0, k = 1, c = 0,5.
La funcin que integra las ecuaciones del movimiento es exactamente la misma que en el caso del lanzamiento. El lector interesado sin duda querr ensayar con sus propias versiones para cometas, satlites o campos electromagnticos.

Figura 5: Elongacin frente a tiempo para un oscilador armnico amortiguado.

Los principales problemas que puede presentar ahora la dinmica de una partcula tienen que ver con la seleccin de las magnitudes adecuadas (unidades y tamao del paso de tiempo) y escribir la ecuacin para la aceleracin en trminos de la posicin y velocidad de la partcula. Pero hallar la trayectoria a partir de la ecuacin se ha convertido en una tarea muy fcil. El cdigo fuerzas.bc presupone que slo se est simulando el movimiento de una partcula. Sin embargo, no es muy difcil generalizar el mtodo a un nmero arbitrario de partculas que interactan. Con pasos de integracin adecuados, es relativamente fcil programar un modelo numrico bsico del sistema solar, por ejemplo. 4.2.2 Campos de fuerzas (campos.bc) Si te encuentras en un examen con un problema en el que tienes que calcular el campo
marcmmw.freeshell.org/esp/programacion/bc.html 23/24

10/07/13

Clculo numrico con bc

elctrico creado por un hilo cargado o una superficie, o algo parecido, normalmente te pedirn que realices el clculo para un punto en el que las operaciones se simplifican bastante a causa de la simetra de la disposicin de cargas. Por ejemplo, para el semicrculo cargado de la figura 6, lo habitual es pedir el campo elctrico en el centro del arco, es decir, el punto (0, 0) de la grfica. Pero calcular el valor del campo en otros puntos se convierte en una tarea bastante ms tediosa. Evidentemente, la mayora de las aplicaciones prcticas de la electrosttica exigen conocer los campos en muchos puntos, no solo donde es fcil calcularlos. El cdigo de campos.bc no es ms que un ejemplo de cmo hacer este tipo de clculos. El resultado se ha representado en la figura 6 usando el programa gratuito gnuplot. Es verdad. Todos estos clculos se Figura 6: Campo elctrico creado por un semicrculo cargado. pueden hacer tambin aprendiendo a manejar algn programa matemtico como Octave, Maxima, Maple o Mathematica. Pero para muchas cosas basta una herramienta relativamente sencilla como bc. La programacin en bc tiene el encanto del bricolaje: cuando terminas, puedes mirar con satisfaccin algo que has hecho t. No hay ninguna duda de que esto tiene mucho valor desde el punto de vista didctico, pero lo que me gustara defender a m es que un ordenador "viejo" no tiene por qu suponer una limitacin. Evidentemente, no podrs jugar a los ltimos juegos de accin sin una tarjeta grfica potente, pero la gran mayora de las cosas que tienes que hacer en una carrera tcnica se pueden hacer con cualquier cacharro. Si a Einstein no le hizo falta tanta potencia de clculo, probablemente tampoco la necesitars t.

marcmmw.freeshell.org/esp/programacion/bc.html

24/24

Das könnte Ihnen auch gefallen