Badillo riosyortizdelaluz

Vivi LeFlo
Vivi LeFloDoofenshmirtz Evil, Inc.

programacion en matlab

UNIVERSIDAD VERACRUZANA 
FACULTAD DE INGENIE RÍA MECÁNICA ELÉCTRICA 
“ M A N U A L D E P R O G R A M A S AP LICADOS A MÉTODOS N U M É R I C O S ” 
TRABAJO PRÁCTICO EDUCATIVO 
PARA ACREDITAR LA EXPERIENCIA EDUCATIVA DE: 
TRABAJO RECEPCIONAL 
P R E S E N T A: 
Juan Ar turo Badi l lo Rios 
José Lui s Or t iz de la luz 
DIRECTOR DE TRABAJO PRÁCTICO EDUCATIVO: 
ISC. KARLOS REYES OR TEGA 
POZA RICA DE HGO; VER. 2011
ÍNDICE 
INTRODUCCIÓN 
CAPITULO I 
1 
JUSTIFICACIÓN 3 
TIPO Y NATURALEZA DEL TRABAJO 3 
CARACTERÍSTICAS Y FUNCIONES ESCENCIALES 
CAPITULO II 
PROCESOS DEL TRABAJO 
3 
1.- ECUACIONES LINEALES 
6 
1.1.- Definición y clasificación 6 
1.2.- Gauss Simple 6 
1.2.1.- Ejemplo propuesto 9 
1.2.2.- Diagrama de Flujo 11 
1.2.3.- Pseudocódigo 13 
1.2.4.- Programas en C 13 
1.2.5.- Demostración del Programa 15 
1.3.- Gauss Seidel 16 
1.3.1.- Ejemplo propuesto 17 
1.3.2.- Diagrama de Flujo 19 
1.3.3.- Pseudocódigo 20 
1.3.4.- Programas en C 21 
1.3.5.- Demostración del Programa 23 
1.4.- Gauss Jordan 25 
1.4.1.- Ejemplo propuesto 25 
1.4.2.- Diagrama de Flujo 28 
1.4.3.- Pseudocódigo 30 
1.4.4.- Programas en C 32
1.4.5.- Demostración del Programa 33 
2.- ECUACIONES NO LINEALES 34 
2.1.- Definición y tipos de ecuaciones no lineales 34 
2.2.- Bisección 35 
2.2.1.- Ejemplo propuesto 36 
2.2.2.- Diagrama de Flujo 39 
2.2.3.- Pseudocódigo 40 
2.2.4.- Programas en C 41 
2.2.5.- Demostración del Programa 42 
2.3.- Falsa Posición 43 
2.3.1.- Ejemplo propuesto 45 
2.3.2.- Diagrama de Flujo 47 
2.3.3.- Pseudocódigo 48 
2.3.4.- Programas en C 49 
2.3.5.- Demostración del Programa 51 
2.4.- Newton-Raphson 52 
2.4.1.- Ejemplo propuesto 53 
2.4.2.- Diagrama de Flujo 55 
2.4.3.- Pseudocódigo 56 
2.4.4.- Programas en C 56 
2.4.5.- Demostración del Programa 57 
3.- ECUACIONES DIFERENCIALES ORDINARIAS 58 
3.1.- Concepto y clasificación 58 
3.2.- Euler 59 
3.2.1.- Ejemplo propuesto 60 
3.2.2.- Diagrama de Flujo 64 
3.2.3.- Pseudocódigo 65
3.2.4.- Programas en C 66 
3.2.5.- Demostración del Programa 67 
3.3.-Runge-Kutta 68 
3.3.1.- Ejemplo propuesto 69 
3.3.2.- Diagrama de Flujo 71 
3.3.3.- Pseudocódigo 72 
3.3.4.- Programas en C 74 
3.3.5.- Demostración del Programa 75 
4.- INTEGRACIÓN 76 
4.1.- Concepto y clasificación 76 
4.2.- Simpson 1/3 76 
4.2.1.- Ejemplo propuesto 77 
4.2.2.- Diagrama de Flujo 80 
4.2.3.- Pseudocódigo 81 
4.2.4.- Programas en C 82 
4.2.5.- Demostración del Programa 83 
COSTOS 
CAPITULO III 
84 
APORTACIONES Y CONTRIBUCIONES AL DESARROLLO 86 
BIBLIOGRAFÍA 87 
ANEXOS 
88
1 
INTRODUCCIÓN 
Los métodos numéricos son técnicas mediante las cuales es posible resolver 
problemas mediante el uso de operaciones aritméticas. Este manual tiene como 
meta dejar plasmados los métodos más importantes que abarca la experiencia 
educativa de métodos numéricos para la solución de sistemas de ecuaciones 
lineales, no lineales y a su vez de derivadas e integrales. Cabe destacar que el 
objetivo fundamental de este trabajo es ofrecer una guía práctica para que los 
estudiantes puedan seguir paso a paso la elaboración de los programas desde el 
desarrollo de los algoritmos a través de los diagramas de flujo hasta la realización 
del código fuente pasando por las etapas de compilación y ejecución exitosa del 
programa.
2 
CAPITULO I
3 
JUSTIFICACIÓN 
Dada la importancia que tienen los métodos numéricos en ingeniería, el alumno 
necesita entender y comprender la experiencia educativa no solo desde un enfoque 
teórico sino también práctico, entendido esto como la generación de los programas 
para aplicar los métodos aprendidos durante la experiencia educativa, brindándoles 
así una herramienta que podrán utilizar en el ámbito laboral y les permitirá ahorrar 
tiempo y esfuerzo, debido a que mediante la aplicación de los métodos numéricos 
es posible manejar sistemas de ecuaciones grandes los cuales de otra forma serian 
difíciles de resolver de forma analítica. 
Sin embargo, ésta materia actualmente no cuenta con un manual para el desarrollo 
de los programas que apliquen los diferentes métodos vistos en clase; por tal 
motivo, éste trabajo pretende ser una guía al momento de cursar esta experiencia y 
ahorrar tiempo al alumno en la investigación del programa, desarrollo y aplicación 
de los mismos. 
TIPO Y NATURALEZA DEL TRABAJO 
El tipo de trabajo es práctico educativo donde la información será seleccionada y 
estructurada con el fin de contribuir en el aprendizaje de los estudiantes y como 
soporte académico para los docentes que imparten la experiencia educativa de 
métodos numéricos dentro de la Universidad Veracruzana, así mismo permitirá 
mejorar las bases para la aplicación de los métodos numéricos mediante programas 
los cuales sirven como herramienta para la solución de problemas en ingeniería. 
CARACTERÍSTICAS Y FUNCIONES ESCENCIALES 
El manual incluirá específicamente los temas de mayor interés para los estudiantes 
de la Facultad de Ingeniería Mecánica Eléctrica, los cuales servirán como apoyo al 
cursar la experiencia educativa de métodos numéricos. 
La función principal de este trabajo, será proporcionar al alumno las bases para 
conocer y aplicar los fundamentos de los métodos numéricos para la solución de 
problemas de ingeniería, implementando diversos algoritmos a través de un 
lenguaje de programación como el Lenguaje C y de esta manera obtener por 
consecuencia programas que permitan mejorar el entendimiento de los métodos 
numéricos.
CAPITULO II
PROCESO 
DEL 
TRABAJO
1.- ECUACIONES LINEALES 
1.1.- Definición y clasificación 
En este capítulo estudiaremos las técnicas de solución de sistemas de ecuaciones 
lineales cuadrados Ax = b. 
Un sistema de ecuaciones lineales, también conocido como sistema lineal de 
ecuaciones o simplemente sistema lineal, es un conjunto de ecuaciones lineales 
sobre un cuerpo o un anillo conmutativo. 
El problema consiste en encontrar los valores desconocidos de las variables x1, x2 y 
x3 que satisfacen las tres ecuaciones. 
Para establecer la velocidad de cálculo y el "trabajo computacional" en los métodos 
directos, se analiza el número de operaciones de éstos y con base en ello se 
determinan sus necesidades de memoria. Como consecuencia de lo anterior, se da 
particular atención a los sistemas especiales: simétricos, bandeados y dispersos, 
entre otros. Así, estudiaremos los métodos que aprovechan estas características 
para lograr reducir con esto el número de operaciones y los requerimientos de 
máquina. 
Posteriormente se exponen y se desarrollan tres métodos numéricos aplicados a las 
ecuaciones lineales como son: Gauss Simple, Gauss Seidel y Gauss Jordan. 
Dado que el mundo real puede verse como un grupo de objetos o partes trabajando 
en conjunto o bien conectadas de alguna manera formando un todo, brindar al 
alumno una mejor comprensión de la extraordinaria cantidad de situaciones que 
pueden representarse con los sistemas o grupos de ecuaciones donde cada una de 
ellas corresponde a alguna de sus partes, por ejemplo: en circuitos, estructuras. 
1.2.- Gauss Simple 
Esta técnica básica puede extenderse a sistemas grandes de ecuaciones 
desarrollando un esquema sistemático o algorítmico para eliminar incógnitas y 
sustituir hacia atrás. 
La eliminación de Gauss es el más básico de dichos esquemas. 
Aquí se presentan las técnicas sistemáticas para la eliminación hacia adelante y la 
sustitución hacia atrás que la eliminación gaussiana comprende. Dado que éstas 
técnicas son muy adecuadas para utilizarse en computadoras, se requieren algunas 
modificaciones para obtener un algoritmo confiable. En particular, el programa debe 
evitar la división entre cero. Al siguiente método se le llama eliminación gaussiana 
simple, ya que no evita este problema. 
6
7 
El método está ideado para resolver un sistema general de n ecuaciones: 
a11x1+a12x2+a13x3+….+a1nxn=b1 (Ec. 1.1a) 
a21x1+a22x2+a23x3+….+a2nxn=b2 (Ec. 1.1b) 
. . 
. . 
an1x1+an2x2+an3x3+….+annxn=bn (Ec. 1.1c) 
Como en el caso de dos ecuaciones, la técnica para resolver ecuaciones consiste 
en dos fases: la eliminación de las incógnitas y su solución mediante sustitución 
hacia atrás. 
La eliminación hacia adelante de incógnitas. La primera fase consiste en reducir el 
conjunto de ecuaciones a un sistema triangular superior (figura 1.1). El paso inicial 
será eliminar la primera incógnita, x1, desde la segunda hasta la n-ésima ecuación. 
Para ello se multiplica la ecuación (Ec. 1.1) por para obtener 
(Ec. 1.2) 
Ahora, esta ecuación se resta de la ecuación (Ec. 1.2) para dar 
O 
Donde el superíndice prima indica que los elementos han cambiado sus valores 
originales
8 
Figura 1.1 
Eliminación 
hacia adelante 
Las dos fases de la eliminación de Gauss: eliminación hacia adelante y sustitución 
hacia atrás. Los superíndices prima indican el número de veces que se han 
modificado los coeficientes y constantes. 
El procedimiento se repite después con las ecuaciones restantes. Por ejemplo, la 
ecuación (Ec. 1.1) se puede multiplicar por y el resultado se resta de la 
tercera ecuación. Se repite el procedimiento con las ecuaciones restantes y da 
como resultado el siguiente sistema modificado: 
a11x1+a12x2+a13x3+….+a1nxn=b1 (Ec. 1.3a) 
a´22x2+a´23x3+….+a´2nxn=b´2 (Ec. 1.3b) 
a´32x2+a´33x3+….+a´3nxn=b´3 (Ec. 1.3c) 
a´n2x2+a´n3x3+….+a´nnxn=b´n (Ec. 1.3d) 
En los pasos anteriores, la ecuación (Ec. 1.1a) se llama la ecuación pivote, y se 
denomina el coeficiente o elemento pivote. Observe que el proceso de multiplicación 
del primer renglón por es equivalente a dividirla entre y multiplicarla por 
. Algunas veces la operación de división es referida a la normalización. Se hace 
esta distinción porque un elemento pivote cero llega a interferir con la normalización 
al causar una división entre cero. Más adelante se regresará a este punto 
importante, una vez que se complete la descripción de la eliminación de Gauss 
simple. 
Ahora se repite el procedimiento antes descrito para eliminar la segunda incógnita 
en las ecuaciones (Ec. 1.3c) hasta (Ec. 1.3d). Para realizar esto, multiplique la 
ecuación (Ec. 1.3b) por y reste el resultado de la ecuación (Ec. 1.3c). Se 
realiza la eliminación en forma similar en las ecuaciones restantes para obtener. 
a11x1+a12x2+a13x3+….+a1nxn=b1 
a´22x2+a´23x3+….+a´2nxn=b´2 
a´´33x3+….+a´´3nxn=b´´3 
. . 
. . 
a´´n2x2+a´´n3x3+….+a´nnxn=b´n 
Sustitución 
hacia atrás
Donde el superíndice biprima indica que los elementos se han modificado dos 
veces. 
El procedimiento puede continuar usando las ecuaciones pivote restantes. La última 
manipulación en esta secuencia es el uso de la ésima ecuación para eliminar 
el término de la -ésima ecuación. Aquí el sistema se habrá transformado en un 
sistema triangular superior 
9 
(Ec. 1.4a) 
(Ec. 1.4b) 
(Ec. 1.4c) 
. . 
. 
. . 
(Ec. 1.4d) 
1.2.1.- Ejemplo propuesto 
Para resolver el siguiente conjunto de ecuaciones. Emplee la eliminación de Gauss 
(Ec.1.5) 
(Ec.1.6) 
(Ec.1.7) 
Las operaciones se efectuarán usando seis cifras significativas. 
La primera parte del procedimiento es la eliminación hacia adelante. Se multiplica la 
ecuación (Ec. 1.5) por (0.1)/3 y se resta el resultado de la ecuación (Ec. 1.6) para 
obtener 
Después, se multiplica la ecuación (Ec. 1.5) por (0.3)/3 y se resta de la ecuación 
(Ec.1.7) para eliminar . Luego de efectuar estas operaciones, el sistema de 
ecuaciones es 
(Ec.1.8) 
(Ec.1.9) 
(Ec.1.10)
Para completar la eliminación hacia adelante, debe eliminarse de la ecuación 
(Ec.1.10). Para llevar a cabo esto, se multiplica la ecuación (Ec.1.9) por - 
0.190000/7.00333 y se resta el resultado de la ecuación (Ec.1.10). Esto elimina 
10 
de la tercera ecuación y reduce el sistema a una forma triangular superior: 
(Ec.1.11) 
(Ec.1.12) 
(Ec.1.13) 
Ahora se pueden resolver estas ecuaciones por sustitución hacia atrás. En primer 
lugar, de la ecuación (Ec.1.13) se despeja x3 
(Ec.1.14) 
Este resultado se sustituye en la ecuación (Ec.1.12): 
7.003332 - 0.293333 (7.00003) = -19.5617 
de la que se despeja 
(Ec.1.15) 
Por último, las ecuaciones (Ec.1.14) y (Ec.1.15) se sustituyen en la (Ec.1.8): 
3 - 0.1 (-2.50000) - 0.2 (7.00003) = 7.85 
de la que se despeja, 
aunque hay un pequeño error de redondeo en la ecuación (Ec.1.14), los resultados 
son muy cercanos a la solución exacta, . Esto se verifica al 
sustituir los resultados en el sistema de ecuaciones original
11 
1.2.2.- Diagrama de flujo 
Diagrama de Flujo Gauss Simple eliminación hacia adelante
12 
Diagrama de Flujo Gauss Simple sustitución hacia atrás
13 
1.2.3.- Pseudocódigo 
a) DO k = 1, n – 1 
DO i = k + 1, n 
factor = 
DO j = k + 1 to n 
ai,j = ai,j – factor . ak,j 
END DO 
bi = bi - factor • 
END DO 
END DO 
b) xn = bn / an,n 
DO i=n-1, 1,-1 
sum = O 
DO j = i + 1, n 
sum = sum + ai,j . xj 
END DO 
xi = (bi - sum) / ai, i 
END DO 
Pseudocódigo que realiza a) la eliminación hacia adelante y b) la sustitución hacia 
atrás. 
1.2.4.- Programas en C 
Gauss Simple 
#include <math.h> 
#include <stdio.h> /*para printf(),scanf()*/ 
#include <conio.h> /*para getch(),clrscr()*/ 
//#include <stdlib.h>/*para exit()*/ 
//#include <dos.h> 
#define NUMEL 20 
#define INTERVALOS 0 
float A[25][25], B[25], S[25],X[25]; 
MAIN 
printf("n METODO DE GAUSS SIMPLE"); 
printf("n Numero de Ecuaciones = "); 
scanf("%d",&n); 
printf("n Inserte cada uno de los coeficientesn"); 
for(i=1;i<=n;i++) 
{ printf("n Fila %d n",i); 
for(j=1;j<=n;j++) 
{ printf(" Ingrese A(%d,%d) = ",i,j); 
scanf("%f",&A[i][j]); 
} 
} 
printf("n Inserte cada uno de los terminos independientesn"); 
for(i=1;i<=n;i++){ 
{ printf(" Ingrese B(%d) = ",i); 
scanf("%f",&B[i]); 
} 
}
14 
printf("n Tolerancia para el calculo = "); 
scanf("%f",&tol); 
Gauss( n,tol, &er ); 
printf("nn RAICES DEL SISTEMAn "); 
for(i=1;i<=n;i++){ 
printf("n X(%d) = %6.4f",i,X[i]); 
} 
printf("nn Fin del programa"); 
getch(); 
} 
void Gauss( int n, float tol, int *er){ 
int i,j; 
// IMPRESION DE LOS COEFICIENTES RECIBIDOS 
/* printf("n IMPRESION DE COEFICIENTESn"); 
for(i=1;i<=n;i++) 
{ printf("n Fila %d n",i); 
for(j=1;j<=n;j++) 
{ printf(" A(%d,%d) = %f",i,j, A[i][j]); 
} 
printf("n"); 
} 
getch(); 
*/ 
*er = 0; 
for (i=1;i<=n;i++){ 
S[i] = abs(A[i][1]); 
for(j=2;j<=n;j++) 
if( abs(A[i][j]>S[i])) 
S[i] = A[i][j]; 
}
15 
1.2.5.- Demostración del programa
1.3.- Gauss Seidel 
El método de Gauss-Seidel emplea valores iniciales y después itera para obtener 
las mejores aproximaciones a la solución. El método de Gauss-Seidel es 
particularmente adecuado cuando se tiene gran número de ecuaciones. Los 
métodos de eliminación pueden estar sujetos a errores de redondeo. Debido a que 
el error en el método de Gauss-Seidel es determinado por el número de iteraciones, 
no es un tema que preocupe. Aunque existen ciertos ejercicios donde la técnica de 
Gauss-Seidel no convergerá al resultado correcto, estudiaremos otras ventajas que 
se tienen dicho método. 
Una matriz bandeada es una matriz cuadrada en donde la diagonal principal son 
valores diferentes a cero (valor=1) y los que se encuentran fuera de la diagonal son 
ceros. Los sistemas bandeados se encuentran con frecuencia en la práctica 
científica y de la ingeniería. Por ejemplo, tales sistemas aparecen en la solución de 
ecuaciones diferenciales. 
Aunque la eliminación de Gauss o la convencional se emplean para resolver 
sistemas de ecuaciones bandeados, resultan ser ineficientes, debido a que si el 
pivoteo no es necesario, ninguno de los elementos fuera de la banda cambiará su 
valor original igual a cero. Así, será necesario utilizar tiempo y espacio en el 
almacenamiento y en el manejo de estos ceros inútiles. Si se sabe de antemano 
que el pivoteo no es necesario, se pueden desarrollar algoritmos muy eficientes en 
los que no intervengan los ceros fuera de la banda. Como en muchos problemas 
con sistemas bandeados, no se requiere el pivoteo; los algoritmos alternos, que se 
describirán a continuación, son los métodos seleccionados para tal fin. 
El método de Gauss-Seidel es el método iterativo más comúnmente usado. 
Suponga que se da un sistema de n ecuaciones: 
Suponga que se limita a un conjunto de ecuaciones de 3 x 3. Si los elementos de la 
diagonal no son todos cero, la primera ecuación se puede resolver para la 
segunda para y la tercera para , para obtener 
16 
(Ec.1.16a) 
(Ec.1.16b) 
(Ec.1.16c) 
Ahora, se puede empezar el proceso de solución al escoger valores iniciales para 
las . Una forma simple para obtener los valores iniciales es suponer que todos son 
cero. Estos ceros se sustituyen en la ecuación (Ec.1.16a), la cual se utiliza para 
calcular un nuevo valor 
Después, se sustituye este nuevo valor de 
junto con el valor previo cero de en la ecuación (Ec.1.16b) y se calcula el 
nuevo valor de . Este proceso se repite con la ecuación (Ec.1.16c) para calcular 
un nuevo valor de . Después se regresa a la primera ecuación y se repite todo el 
procedimiento hasta que la solución converja suficientemente cerca de los valores 
verdaderos. La convergencia se verifica usando el criterio de la siguiente ecuación 
de error relativo porcentual.
17 
(Ec.1.17) 
Para toda las donde y son las iteraciones actuales y previas 
respectivamente. 
1.3.1.- Ejemplo propuesto 
Planteamiento del problema. Use el método de Gauss-Seidel para obtener la 
solución del sistema usado en el ejemplo: 
Recuerde que la verdadera solución es . 
Solución. Primero, despeje la incógnita sobre la diagonal para cada una de las 
ecuaciones. 
(Ec.1.18a) 
(Ec.1.18b) 
(Ec.1.18c) 
Suponiendo que son cero, se utiliza la ecuación (Ec.1.18a) para calcular 
Este valor, junto con el valor de = 0, se sustituye en la ecuación (Ec.1.18b) para 
calcular
18 
la primera iteración termina al sustituir los valores calculados para en la 
ecuación (Ec.1.18c) para dar 
en la segunda iteración, se repite el mismo proceso para calcular 
El método es, por lo tanto, convergente hacia la verdadera solución. Es posible 
aplicar iteraciones adicionales para mejorar los resultados. Sin embargo, es un 
problema real no se podría saber con anticipación el resultado correcto. En 
consecuencia, la ecuación (Ec.1.17) nos da un medio para estimar el error relativo 
porcentual. Por ejemplo, para , 
Para los errores estimados son . Observe 
que, como cuando se determinaron las raíces de una sola ecuación, las 
formulaciones como la ecuación (Ec.1.17) de Error relativo porcentual, usualmente 
ofrecen una valoración conservativa de la convergencia. Así, cuando estas se 
satisfacen aseguran que el resultado se conozca con al menos, la tolerancia 
especificada por .
19 
1.3.2.- Diagrama de flujo 
Diagrama de Flujo Gauss Seidel
20 
1.3.3.- Pseudocódigo 
SUBROUTINE Gseid (a, b, n, x, imax, es, lambda) 
DO i = 1,n 
dummy = ai.i 
DO j = 1,n 
ai,j = ai,j / dummy 
END DO 
bi = ai / dummy 
END DO 
DO i = 1, n 
sum = bi 
DO j = 1, n 
IF i j THEN sum =sum – ai, j *xj 
END DO 
xi = sum 
END DO 
iter =1 
DO 
centinela = 1 
DO i = 1, n 
old = xi 
sum = bi 
DO j = 1, n 
IF i j THEN sum =sum – ai, j *xj 
END DO 
xi = lambda * sum +( 1 - lambda) * old 
IF centinela = 1 AND x1 0 . THEN 
ea=ABS (( xi –old) / xi )*100. 
IF ea es THEN centinela = 0 
END IF 
END DO 
iter = iter + 1 
IF centinela = 1 OR (iter I max) EXIT 
END DO 
END Gseid
21 
1.3.4. - Programas en C 
GAUSS SEIDEL 
#include <stdio.h> 
#include <math.h> 
#include <iostream.h> 
#include <conio.h> 
#define L 10 
#define P L 
MAIN 
cout<<"nn METODO DE GAUSS SEIDEL "; 
cout<<"nn Numero de incognitas Posibles en el sistema: "; 
scanf("%d",&n); 
Gauss_Seidel(n); 
titulo(n); 
resultados(); 
cout<<"nnLos resultado son "; 
for(x=0;x<n;x++) 
{ 
RESULTADOS[x]=X[x]; 
cout<<"nX["<<x<<"]= "<<RESULTADOS[x]; 
} 
getch(); 
} 
void resultados() 
{ 
int q=0,i=1,t=3,s=n,r=0; 
int sw=0,w=0,ite=0,h=0; 
while((sw==0)&&(w<20)) 
{ 
h=0; 
while(h<n) 
{ 
if(tabla[r]==tabla[r+s]) 
{ 
cont++; 
} 
if(cont==n) 
sw=1; 
r++; 
s++; 
h++; 
} 
ite++; 
w++; 
} 
w=ite-1; 
for(int j=0;j<w;j++) 
{ 
t=t+2; 
if((i%10==0)) 
{ 
textcolor(LIGHTRED+BLINK); 
gotoxy(5,t-2); 
cprintf("nn ­­­Presione 
una tecla para ingresar ala tabla!!! "); 
getch(); 
textcolor(GREEN); 
clrscr(); 
t=5; 
titulo(n); 
} 
gotoxy(15,t);cout<<i<<"ø"; 
int y=20,z=0; 
for(int r=0;r<n;r++)
22 
{ 
gotoxy(y+z,t);cout<<tabla[q]; 
q++; 
z=z+10; 
} 
i++; 
} 
} 
void main() 
{
23 
1.3.5.- Demostración del programa
24
25 
1.4.- Gauss Jordan 
El método de Gauss-Jordan es una variación de la eliminación de Gauss. La 
principal diferencia consiste en que cuando una incógnita se elimina en el método 
de Gauss-Jordan. Ésta es eliminada de todas las otras ecuaciones, no sólo de las 
subsecuentes. Además, todos los renglones se normalizan al dividirlos entre su 
elemento pivote. De esta forma, el paso de eliminación genera una matriz identidad 
en vez de una triangular (figura 1.2). En consecuencia, no es necesario usar la 
sustitución hacia atrás para obtener la solución. El método se ilustra mejor con un 
ejemplo. 
Figura 1.2 
Representación gráfica del método de Gauss-Jordan. 
1.4.1.- Ejemplo propuesto 
Método de Gauss-Jordan 
Para resolver el siguiente conjunto de ecuaciones. Con la técnica de Gauss-Jordan 
Solución. Primero, exprese los coeficientes y el lado derecho como una matriz au-mentada 
3 -0.1 -0.2 7.85 
0.1 7 -0.3 -19.3 
0 -0.2 10 71.4
Luego normalice el primer renglón, dividiéndolo entre el elemento pivote, 3, para 
obtener 
26 
1 -0.0333333 -0.066667 2.61667 
0.1 7 -0.3 -19.3 
0.3 -0.2 10 71.4 
El término se elimina del segundo renglón restando 0.1 veces al primer renglón del 
segundo. En forma similar, restando 0.3 veces el primer renglón del tercero, se 
eliminará el término del tercer renglón: 
1 -0.0333333 -0.066667 2.61667 
0 7.00333 -0.293333 -19.5617 
0 -0.190000 10.0200 70.6150 
En seguida, se normaliza el segundo renglón dividiéndolo entre 7.00333: 
1 -0.0333333 -0.066667 2.61667 
0 1 -0.0418848 - 2.79320 
0 -0.190000 10.0200 70.6150 
Al reducir los términos x2 de las ecuaciones primera y tercera se obtiene 
1 0 -0.0680629 2.52356 
0 1 -0.0418848 -2.79320 
0 0 10.01200 70.0843 
El tercer renglón se normaliza después al dividirlo entre 10.0120: 
1 0 -0.0680629 2.52356 
0 1 -0.0418848 -2.79320 
0 0 1 7.00003
Por último los términos se pueden eliminar de la primera y segunda ecuación para 
obtener 
27 
1 0 0 3.00000 
0 1 0 -2.50001 
0 0 1 7.00003 
De esta forma, como se muestra en la figura 1.2 la matriz de coeficientes se ha 
transformado en la matriz identidad, y la solución se obtiene en el vector del lado 
derecho. Observe que no se requiere la sustitución hacia atrás para llegar a la 
solución.
28 
1.4.2.- Diagrama de Flujo 
N,M,I,A,J 
Diagrama de Flujo Gauss Jordan
29 
SUBROUTINE 
GAUSS (N,M,A) 
I,PIVOTE,A,J,K,N, 
M,CERO 
Diagrama de Flujo principal Gauss Jordan subrutina
30 
1.4.3.- Pseudocódigo 
SUB Gauss (a, b, n, x, tol, er) 
DIMENSION s (n) 
er = 0 
DO i =l, n 
si = ABS (ai,1 ) 
DO j = 2, n 
IF ABS (Ai,j) si THEN si = abs (a i , j) 
END DO 
END DO 
SUB Eliminate (a, s, n, b, tol, er) 
IF er -1 THEN 
CALL Substitute (a , n , b, x) 
END IF 
END Gauss 
CALL Eliminate (a, s, n, b, tol, er) 
DO k = 1, n – 1 
CALL Pivot (a, b, s, n, k) 
IF ABS (ak, k/ sk) tol THEN 
er = -1 
EXIT DO 
END IF 
DO i = k +1, n 
factor = a i, k/ a k, k 
DO j= k + 1, n 
ai,j = a i, j - factor*ak,j 
END DO 
bi = bi – factor * bk 
END DO 
END DO 
IF ABS (ak,k / sk) tol THEN er = -1 
END Eliminate
31 
SUB Pivot (a, b, s, n, k) 
p=k 
big = ABS(ak,k/sk) 
DO i i= k + 1, n 
dummy = ABS(aii,k/sii) 
IF dummy > big THEN 
big = dummy 
p = i i 
END IF 
END DO 
IF p k THEN 
DO jj = k, n 
dummy = ap, jj 
ap, jj = ak, jj 
ak, jj = dummy 
END DO 
dummy = bp 
bp = bk 
bk = dummy 
dummy = sp 
sp = sk 
sk = dummy 
END IF 
END pivot 
SUB Substitute (a, n, b, x) 
xn = bn / an,n 
DO i = n – 1, 1, -1 
sum = 0 
DO j = i + 1, n 
sum = sum + ai,j * xj 
END DO 
xi = (bi – sum) / ai,i 
END DO 
END Substitute
32 
1.4.4.- Programas en C 
GAUSS JORDAN 
#include <math.h> 
#include <stdio.h> /*para printf(),scanf()*/ 
#include <conio.h> /*para getch(),clrscr()*/ 
//#include <stdlib.h>/*para exit()*/ 
//#include <dos.h> 
#define NUMEL 20 
#define INTERVALOS 0 
float A[25][25], B[25], S[25],X[25]; 
MAIN 
printf("n METODO DE GAUSS JORDAN"); 
printf("nn Ingrese el numero de incognitas nn Numero de Ecuaciones = "); 
scanf("%d",&n); 
printf("n Inserte cada uno de los coeficientesn"); 
for(i=1;i<=n;i++) 
{ printf("n Fila %d n",i); 
for(j=1;j<=n+1;j++) 
{ printf(" Ingrese a(%d,%d) = ",i,j); 
scanf("%f",&a[i][j]); 
} 
} 
m=n+1; 
do 
{ if(a[1][1]==0) 
{k=m-1; 
for(i=2;i<=k;i++) 
{if(a[i][1]!=0) 
{for(j=1;j<=m;j++) 
{ apoyo=a[i][j]; 
a[i][j]=a[1][j]; 
a[1][j]=apoyo; 
} 
} 
} 
} 
else 
{for(j=2;j<=m;j++) 
{for(i=2;i<=n;i++) 
{b[i-1][j-1]=a[i][j]-a[1][j]*a[i][1]/a[1][1];} 
} 
for(j=2;j<=m;j++) 
{b[n][j-1]=a[1][j]/a[1][1];} 
m=m-1; 
for(j=1;j<=m;j++) 
{for(i=1;i<=n;i++) 
{a[i][j]=b[i][j];} 
} 
} 
} 
while(m>1); 
printf("nn RAICES DEL SISTEMAn "); 
for(i=1;i<=n;i++) 
{printf("n X(%d) = %1.4f",i,a[i][1]);} 
printf("nn Fin del programa"); 
getch(); 
} 
}
33 
1.4.5.- Demostración del programa
2.- ECUACIONES NO LINEALES 
2.1.- Definición y tipos de ecuaciones no lineales 
En este capítulo estudiaremos diversos métodos para resolver ecuaciones no lineales 
en una incógnita , aprovechando los conceptos básicos del cálculo y las 
posibilidades gráficas y de cómputo de la tecnología moderna. Sistemáticamente a la 
interpretación gráfica de los métodos, a fin de mostrar visualmente su funcionamiento y 
de enriquecer las imágenes asociadas con ellos; de igual manera, se generan tablas 
en la aplicación de cada técnica para analizar el comportamiento numérico y 
eventualmente detener el proceso. 
Se ha organizado el material como métodos de uno y dos puntos, de los segundos el 
de posición falsa. Esto, junto con el concepto de orden de convergencia, nos permitirá 
tener los elementos suficientes para seleccionar la técnica más adecuada para una 
situación dada. Finalizamos el capítulo con las técnicas para resolver ecuaciones 
polinomiales. El propósito de este capítulo es que el estudiante cuente con los 
elementos básicos, computacionales y de criterio, apropiados para resolver el 
problema algebraico clásico de encontrar las raíces reales y complejas de la ecuación 
, en donde las técnicas algebraicas de "despejar" la incógnita no sean 
aplicables, como es el caso de , o bien resulten imprácticas. 
Por último, es importante señalar lo difícil que resulta pensar en un tópico de 
matemáticas o ingeniería que no involucre ecuaciones de esta naturaleza. 
La solución de este sistema consta de un conjunto de valores que simultáneamente 
hacen que todas las ecuaciones sean iguales a cero. 
Presentamos los métodos, para el caso en que las ecuaciones simultáneas son 
lineales, es decir, que se puedan expresar en la forma general 
donde la b y la a son constantes. A las ecuaciones algebraicas y trascendentales que 
no se pueden expresar de esta forma se les llama ecuaciones no lineales. Por ejemplo, 
34 
Y 
son dos ecuaciones simultáneas no lineales con dos incógnitas, y , las cuales se 
expresan en la forma de la ecuación como 
Así, la solución serían los valores de y de y que hacen a las funciones y 
iguales a cero. La mayoría de los métodos para determinar tales soluciones son 
extensiones de los métodos abiertos para resolver ecuaciones simples.
2.2.- Bisección 
Al aplicar las técnicas gráficas se observa que cambia de signo a ambos lados 
de la raíz. En general, si es real y continúa en el intervalo que va desde hasta 
35 
y y tienen signos opuestos, es decir, 
(Ec.2.1) 
entonces hay al menos una raíz real entre y . 
Los métodos de búsqueda incremental aprovechan esta característica localizando 
un intervalo en el que la función cambie de signo. Entonces, la localización del 
cambio de signo (y, en consecuencia, de la raíz) se logra con más exactitud al dividir 
el intervalo en varios subintervalos. Se investiga cada uno de estos subintervalos 
para encontrar el cambio de signo. El proceso se repite y la aproximación a la raíz 
mejora cada vez más en la medida que los subintervalos se dividen en intervalos 
cada vez más pequeños. 
Figura 2.1
El método de bisección, conocido también como de corte binario, de partición de 
intervalos o de Bolzano, es un tipo de búsqueda incremental en el que el intervalo 
se divide siempre a la mitad. Si la función cambia de signo sobre un intervalo, se 
evalúa el valor de la función en el punto medio. La posición de la raíz se determina 
situándola sobre el punto medio del subintervalo, dentro del cual ocurre un cambio 
de signo. El proceso se repite hasta obtener una mejor aproximación. En la figura 
2.1 se presenta un algoritmo sencillo para los cálculos de la bisección. En la figura 
2.3 se muestra una representación gráfica del método. Los siguientes ejemplos se 
harán a través de cálculos reales involucrados en el método. 
36 
2.2.1.- Ejemplo propuesto 
Planteamiento del problema. Emplee el método de bisección para resolver el 
siguiente problema. 
Figura 2.2 
El método gráfico para determinar las raíces de una ecuación 
Solución. El primer paso del método de bisección consiste en asignar dos valores 
iniciales a la incógnita (en este problema, c) que den valores de con diferentes 
signos. En la figura 2.2 se observa que la función cambia de signo entre los valores 
12 y 16. Por lo tanto, la estimación inicial de la raíz se encontrará en el punto 
medio del intervalo 
Dicha aproximación representa un error relativo porcentual verdadero de 
(note que el valor verdadero de la raíz es 14.7802). A continuación calculamos el 
producto de los valores en la función en un límite inferior y en el punto medio:
que es mayor a cero y, por lo tanto, no ocurre cambio de signo entre el límite 
inferior y el punto medio. En consecuencia, la raíz debe estar localizada entre 14 y 
16. 
Entonces, se crea un nuevo intervalo redefiniendo el límite inferior como 14 y 
determinando una nueva aproximación corregida de la raíz 
37 
Figura 2.3 
Una representación gráfica del método de bisección. La gráfica presenta las 
primeras tres iteraciones del ejemplo 2.2.1 
la cual representa un error porcentual verdadero , = 1.5%. Este proceso se repite 
para obtener una mejor aproximación. Por ejemplo,
Por lo tanto, la raíz está entre 14 y 15. El límite superior se redefine como 15 y la 
raíz estimada para la tercera iteración se calcula así: 
que representa un error relativo porcentual , = 1 .9%. Este método se repite 
hasta que el resultado sea suficientemente exacto para satisfacer sus necesidades. 
En el ejemplo anterior, se observa que el error verdadero no disminuye con cada 
iteración. Sin embargo, el intervalo donde se localiza la raíz se divide a la mitad en 
cada paso del proceso. Como se estudiará en la siguiente sección, el ancho del 
intervalo proporciona una estimación exacta del límite superior del error en el 
método de bisección. 
38
39 
2.2.2.- Diagrama de Flujo 
Diagrama de Flujo Bisección
40 
2.2.3.- Pseudocódigo 
FUNCTION Bisect(xl, xu, es, imax, xr, iter, ea) 
iter = 0 
fl = f(xl) 
DO 
xrold = xr 
xr = (xl + xu) / 2 
fr = f( xr ) 
iter = iter + 1 
IF xr 0 THEN 
ea = ABS((xr – xrold) / xr) * 100 
END IF 
test = fl * fr 
IF test 0 THEN 
xu = xr 
ELSE IF test 0 THEN 
xl = xr 
fl= fr 
ELSE 
ea = 0 
END IF 
IF ea es OR iter imax EXIT 
END DO 
Bisect = xr 
END Bisect
41 
2.2.4.- Programas en C 
BISECCIÓN 
#include <math.h> 
#include <stdio.h> /*para printf(),scanf()*/ 
#include <conio.h> /*para getch(),clrscr()*/ 
//#include <stdlib.h>/*para exit()*/ 
//#include <dos.h> 
#define NUMEL 20 
#define INTERVALOS 0 
float A[25][25], B[25], S[25],X[25]; 
MAIN 
printf("n METODO DE BISECCIONn"); 
printf( " Teclea valor minimo = "); 
scanf("%f",&xmin); 
printf("n"); 
printf( " Teclea valor maximo = "); 
scanf("%f",&xmax); 
printf("n"); 
printf( " Teclea valor de error esperado = "); 
scanf("%f",&error); 
printf("n"); 
printf( " Teclea iteraciones maximas = "); 
scanf("%f",&iteraciones); 
printf("n"); 
c1 = Bisect(xmin, xmax, error, iteraciones); 
printf( " Resultado = %f", c1); 
getch(); 
} 
} 
float Bisect( float x1,float xu, float es, int imax){ 
int iter; 
float f1, fr, test; 
float xold, xr, ea=0; 
iter = 0; 
f1 = F(x1, 10, 40, 68.1); 
do{ 
xold = xr; 
xr = (x1+xu)/2; 
iter = iter +1; 
if( xr != 0 ){ 
ea = abs((xr-xold)/xr)*100; 
} 
fr = F(xr, 10, 40, 68.1); 
test = f1*fr; 
if( test < 0 ){ // Se determina si hay una raiz entre x1 y xr, cambio de signo 
xu = xr; 
} 
else if ( test > 0 ) { 
x1 = xr; 
f1 = fr; 
} 
else // Se encontro una raiz 
ea = 0; 
// imprimimos los resultados 
printf( " No X1 Xu Xr ea etn"); 
printf( " %d %6.3f %6.3f %6.3f %6.3f %6.3f n", iter, x1, xu, xr, ea ) ; 
}while( (ea >= es) || (iter<imax)); 
return xr; 
}
42 
2.2.5.- Demostración del programa
43 
2.3.- Falsa Posición 
Aun cuando la bisección es una técnica perfectamente válida para determinar 
raíces, su método de aproximación por "fuerza bruta" es relativamente ineficiente. 
La falsa posición es una alternativa basada en una visualización gráfica. 
Un inconveniente del método de bisección es que al dividir el intervalo de , a 
en mitades iguales, no se toman en consideración las magnitudes de y 
de . Por ejemplo, si de está mucho más cercana a cero que de , es 
lógico que la raíz se encuentre más cerca de que de (figura 2.4). Un método 
alternativo que aprovecha esta visualización gráfica consiste en unir y 
con una línea recta. La intersección de esta línea con el eje de las x representa una 
mejor aproximación de la raíz. El hecho de que se reemplace la curva por una línea 
recta da una "falsa posición" de la raíz; de aquí el nombre de método de la falsa 
posición, o en latín, regula falsi. También se le conoce como método de 
interpolación lineal. 
Usando triángulos semejantes (fig.2.4) la intersección de la línea recta con el eje de 
las se estima mediante 
(Ec. 2.2) 
en el cual se despeja 
(Ec. 2.3) 
Ésta es la fórmula de la falsa posición. El valor de calculado con la ecuación 
(Ec. 2.3), reemplazará, después, a cualquiera de los dos valores iniciales, o , y 
da un valor de la función con el mismo signo de . De esta manera, los valores 
o siempre encierran la verdadera raíz. El proceso se repite hasta que la 
aproximación a la raíz sea adecuada. El algoritmo es idéntico al de la bisección 
(figura 2.1), excepto en que la ecuación (Ec. 2.3).
44 
Figura 2.4 
Representación gráfica del método de la falsa posición con los triángulos 
semejantes sombreados se obtiene la fórmula para el método. 
Desarrollo del método de la falsa posición 
Multiplicando en cruz la ecuación (2.2) obtenemos 
Agrupando términos y reordenando: 
Dividiendo entre 
(Ec. 2.3a) 
Ésta es una de las formas del método de la falsa posición. Observe que permite el 
cálculo de la raíz como una función de los valores iniciales inferior y 
superior . Ésta puede ponerse en una forma alternativa al separar los términos: 
Sumando y restando en el lado derecho:
45 
Agrupando términos se obtiene 
O 
La cual es la misma ecuación (Ec. 2.3). Se utiliza esta forma porque implica una 
evaluación de la función y una multiplicación menos que la ecuación (Ec. 2.3a). 
2.3.1.- Ejemplo propuesto 
Con el método de la falsa posición determine la raíz de la misma ecuación 
analizada en el ejemplo 2.3 [ecuación (Ec. 2.3a)]. 
Solución. Se empieza el cálculo con los valores iniciales =12 y = 16. 
Primera iteración: 
= 12 = 6.0699 
=16 = -2.2688 
que tiene un error relativo verdadero de 0.89 por ciento. 
Segunda iteración: 
o = -1.5426 
Por lo tanto, la raíz se encuentra en el primer subintervalo y xr se vuelve ahora el 
límite superior para la siguiente iteración, = 14.9113: 
= 12 
= 14.9113 f
el cual tiene errores relativos y verdadero y aproximado de 0.09 y 0.79 por ciento. 
Es posible realizar iteraciones adicionales para hacer una mejor aproximación de 
las raíces. 
Se obtiene una idea más completa de la eficiencia de los métodos de bisección y 
de falsa posición al observar la figura 3.5 donde se muestra el error relativo 
porcentual verdadero de los ejemplos 3.3 y 3.3.1. Observe cómo el error decrece 
mucho más rápidamente en el método de la falsa posición que en el de la 
bisección, debido a un esquema más eficiente en el método de la falsa posición 
para la localización de raíces. 
Recuerde que en el método de bisección el intervalo entre y se va 
haciendo más pequeño durante los cálculos. Por lo tanto, el intervalo, como se 
define para la primera iteración, proporciona una medida del error en este método. 
Éste no es el caso con el método de la falsa posición, ya que uno de los valores 
iniciales puede permanecer fijo durante los cálculos, mientras que el otro converge 
hacia la raíz. Como en el caso del ejemplo, el extremo inferior permanece en 12, 
mientras que converge a la raíz. En tales casos, el intervalo no se acorta, sino 
que se aproxima a un valor constante. 
46 
Figura 2.5 
Comparación de los errores relativos de los métodos de bisección y de falsa 
posición
47 
2.3.2.- Diagrama de Flujo 
Diagrama de Flujo Falsa Posición
48 
2.3.3.- Pseudocódigo 
FUNCTION ModFalsepos (xl, xu, es, imax, xr, iter, ea) 
iter = 0 
fl = f(xl) 
fu = f (xu) 
DO 
xrold = xr 
xr = xu – fu * (xl – xu) / (fl – fu) 
fr = f(xr) 
iter= iter+1 
IF xr 0 THEN 
ea = Abs((xr – xrold) / xr) * 100 
END IF 
test = fl * fr 
IF test 0 THEN 
xu = xr 
fu = f(xu) 
iu= 0 
il = il + 1 
IF il 2 THEN fl = fl / 2 
ELSE IF test O THEN 
xl=xr 
fl = f (xl) 
il=0 
iu = iu + 1 
IF iu 2 THEN fu =fu / 2 
ELSE 
ea = 0 
END IF 
IF ea es OR iter imax THEN EXIT 
END DO 
modFalsepos = xr 
END Modfalsepos
49 
2.3.4.- Programas en C 
#include <math.h> 
#include <stdio.h> /*para printf(),scanf()*/ 
#include <conio.h> /*para getch(),clrscr()*/ 
//#include <stdlib.h>/*para exit()*/ 
//#include <dos.h> 
#define NUMEL 20 
#define INTERVALOS 0 
float A[25][25], B[25], S[25],X[25]; 
MAIN 
printf("n METODO DE FALSA POSICIONn"); 
printf( " Teclea valor minimo = "); 
scanf("%f",&xmin); 
printf("n"); 
printf( " Teclea valor maximo = "); 
scanf("%f",&xmax); 
printf("n"); 
printf( " Teclea valor de error esperado = "); 
scanf("%f",&error); 
printf("n"); 
printf( " Teclea iteraciones maximas = "); 
scanf("%f",&iteraciones); 
printf("n"); 
c1 = Bisect(xmin, xmax, error, iteraciones); 
c1 = FalsePos( xmin, xmax, error, iteraciones); 
printf( " Resultado = %f", c1); 
getch(); 
} 
}
50 
float FalsePos( float x1,float xu, float es, int imax){ 
int iter=0, i1, iu; 
float f1, fr, fu, test; 
float xrold, xr, ea=0; 
f1 = F(x1, 10, 40, 68.1); 
fu = F(xu, 10, 40, 68.1); 
do{ 
xrold = xr; 
xr = xu-fu*(x1-xu)/(f1-fu); 
fr = F(xr,10,40,68.1); 
iter = iter +1; 
if ( xr != 0 ) { 
ea = abs( (xr - xrold)/xr )* 100; 
} 
test = f1 * fr; 
if( test < 0 ) { 
xu = xr; 
fu = F(xu, 10, 40, 68.1); 
iu = 0; 
i1 = i1 + 1; 
if ( i1 >= 2 )f1 = f1 / 2; 
} 
else if ( test > 0 ){ 
x1 = xr; 
f1 = F(x1, 10, 40, 68.1); 
i1 = 0; 
iu = iu +1; 
if( iu >= 2) fu = fu / 2; 
} 
else ea=0; 
}while( (ea >= es) || (iter<imax)); 
return xr; 
}
51 
2.3.5.- Demostración del programa
2.4.- Newton-Raphson 
Tal vez, de las fórmulas para localizar raíces, la fórmula de Newton-Raphson 
(figura 2.6) sea la más ampliamente utilizada. Si el valor inicial para la raíz es , 
entonces se puede trazar una tangente desde el punto [ , ] de la curva. Por lo 
común, el punto donde esta tangente cruza al eje x representa una aproximación 
mejorada de la raíz. 
El método de Newton-Raphson se deduce a partir de esta interpretación 
geométrica. De la figura 2.4, se tiene que la primera derivada en es equivalente a 
la pendiente: 
52 
Figura 2.6 
Representación gráfica del método de Newton Raphson. Se extrapola una tangente 
a la función en [esto es, ] hasta el eje x para obtener una estimación de la 
raíz en . 
f´ f 
(Ec.2.4) 
que se reordena para obtener 
f 
f´ 
(Ec.2.5) 
La cual se conoce como fórmula de Newton-Raphson.
2.4.1.- Ejemplo propuesto 
Planteamiento del problema. Utilice el método de Newton-Raphson para calcular 
la raíz de empleando como valor inicial y se considere 
como raíz real la iteración en donde exista una similitud de al menos 6 cifras 
significativas con la iteración anterior. 
Solución. La primera derivada de la función es 
53 
que se sustituye, junto con la función original en la ecuación (2.5), para tener
54 
Empezando con un valor inicial , se obtuvieron los siguientes resultados: 
0 0 100 ' 
1 0.500000000 11.8 
2 0.566311003 0.147 
3 0.567143165 0.0000220 
4 0.567143290 < 
Así, el método converge rápidamente a la raíz verdadera. Observe que el error 
relativo porcentual verdadero en cada iteración disminuye mucho más rápido que 
con la iteración simple de punto fijo.
55 
2.4.2.- Diagrama de Flujo 
No convergen en 
NMI iteraciones 
Diagrama de Flujo Newton Raphson 
INICIO 
NGRAD,N,M,I,A,A 
PROX,NRAIZ,X,N 
MI,B,C,Y,REL
56 
2.4.3.- Pseudocódigo 
function newtonIterationFunction(x) { 
return x - (cos(x) - x^3) / (-sin(x) - 3*x^2) 
} 
var x := 0,5 
for i from 0 to 99 { 
print "Iteraciones: " i 
print "Valor aproximado: " x 
xold := x 
x := newtonIterationFunction(x) 
if x = xold { 
print "Solución encontrada!" 
break 
} 
} 
2.4.4.- Programas en C 
NEWTON RAPHSON 
#include <conio.h> 
#include <stdio.h> 
#include <math.h> 
MAIN 
printf("ttMETODO DE NEWTON RAPHSON"); 
printf("nnintruce valor inicial"); 
printf("nnX="); 
scanf("%f",&x1); 
printf("nIteraciones="); 
scanf("%d",&I); 
do 
{ 
y=exp(-x1)-x1; 
y2=-1*exp(-x1)-1; 
xr=x1 - (y/y2); 
a=((xr-x1)/xr)*100; 
e=fabs(a); 
x1=xr; 
i++; 
c++; 
} 
while(i<I); 
printf("nnnnLa raiz aproximada es x%d = %.12f ",c,xr); 
printf("nnError = %.3f",e); 
getch(); 
}
57 
2.4.3.- Demostración del programa
3.- ECUACIONES DIFERENCIALES ORDINARIAS 
3.1.- Concepto y clasificación 
En este capítulo se estudiarán, las técnicas numéricas de solución de ecuaciones 
diferenciales con condiciones iniciales o de frontera, denominados problemas de valor 
inicial o de frontera, respectivamente. Una ecuación diferencial ordinaria 
(comúnmente abreviada "EDO") es una relación que contiene funciones de una sola 
variable independiente, y una o más de sus derivadas con respecto a esa variable. 
Para esto, se inicia formulando tales problemas, y luego, a partir de las ideas de 
extrapolación, se plantean métodos como el de Euler. Más adelante, en un proceso 
de ponderación de pendientes, se obtienen métodos con diferentes órdenes de 
exactitud donde no se requiere de derivaciones complicadas de funciones, pagándose 
como precio de ello un mayor número de cálculos. Tales métodos son conocidos 
como métodos de Runge-Kutta. Basándose en el proceso de integración implicado en 
la solución de las ecuaciones diferenciales y en la aproximación de funciones se 
plantean familias de métodos denominados de predicción-corrección. 
Dado que las ecuaciones diferenciales ordinarias permiten modelar procesos diná-micos 
tales como: vaciado de recipientes, reactores químicos, movimientos 
amortiguados, desarrollos poblacionales e incluso situaciones estáticas como la 
deflexión de vigas y problemas geométricos. Estas técnicas analíticas son necesarias 
para ciertas ecuaciones muy particulares. 
Muchas de las leyes generales de la naturaleza se expresan en el lenguaje de las 
ecuaciones diferenciales; abundan también las aplicaciones en ingeniería, economía, 
en las mismas matemáticas y en muchos otros campos de la ciencia aplicada. 
Esta gran utilidad de las ecuaciones diferenciales es fácil de explicar; recuérdese que 
si se tiene la función su derivada puede interpretarse como la 
velocidad de cambio de y con respecto a . En cualquier proceso natural, las variables 
incluidas y sus velocidades de cambio se relacionan entre sí mediante los principios 
científicos que gobiernan el proceso. El resultado de expresar en símbolos 
matemáticos estas relaciones, a menudo es una ecuación diferencial. 
58
59 
3.2.- Euler 
Este tema se refiere a la solución de ecuaciones diferenciales ordinarias de la forma 
Recuerde que el método fue de la forma general 
Nuevo valor = valor anterior + pendiente x tamaño de paso 
o, en términos matemáticos, 
(Ec.3.2) 
De acuerdo con esta ecuación, la pendiente estimada se usa para extrapolar desde 
un valor anterior a un nuevo valor en una distancia (figura 3.1). Esta fórmula 
se aplica paso a paso para calcular un valor posterior y, por lo tanto, para trazar la 
trayectoria de la solución. 
En otras palabras, se toma la pendiente al inicio del intervalo como una aproximación 
de la pendiente promedio sobre todo el intervalo. 
Figura 3.1 
Ilustración gráfica del método de un paso.
60 
La primera derivada ofrece una estimación directa de la pendiente en (figura 3.2): 
donde es la ecuación diferencial evaluada en y . La estimación se 
sustituye la ecuación (Ec.3.1): 
f (Ec.3.2) 
Esta fórmula se conoce como método de Euler (o de Euler-Cauchy o de punto 
pendiente). Se predice un nuevo valor de y, usando la pendiente (igual a la primera 
deriva en el valor original de x) para extrapolar linealmente sobre el tamaño de paso h 
(figura 3.2). 
Figura 3.2 
Método de Euler. 
3.2.1.- Ejemplo propuesto 
Planteamiento del problema. Con el método de Euler integre numéricamente la 
ecuación 
desde hasta con un tamaño de paso 0.5. La condición inicial en 
es . Recuerde que la solución exacta está dada por la siguiente ecuación:
61 
Solución. Se utiliza la ecuación (Ec.3.2) para implementar el método de 
Euler: 
donde y la pendiente estimada en es 
Por lo tanto, 
La solución verdadera en es 
Así, el error es 
Et = valor verdadero - valor aproximado 
o , expresada como error relativo porcentual, t = -63.1%. En el segundo paso, 
La solución verdadera en x = 1.0 es 3.0 y, entonces, el error relativo porcentual es - 
95.8%. El cálculo se repite y los resultados se dan en la tabla 3.2.1 y en la figura 3.3. 
Comparación de los valores verdadero y aproximado de la integral de y'= -2X3+ 1 
2.x2 - 20x + 8.5, con la condición inicial de que y = 1 en x = 0. Los valores 
aproximados se calcularon empleando el método de Euler con un tamaño de paso de 
0.5. El error local se refiere al error en que se incurre sobre un solo paso. Éste se 
calcula con una expansión de la serie de Taylor como en el ejemplo 3.3. El error 
global es la discrepancia total debida a los pasos anteriores y presentes.
62 
Tabla 3.2.1 
Error relativo 
porcentual 
X Y verdadero Y euler Global Local 
0.0 1 .00000 1 .00000 
0.5 3.21875 5.25000 -63.1 -63.1 
1.0 3.00000 5.87500 -95.8 -28.0 
1.5 2.21875 5.12500 131.0 -1.41 
2.0 2.00000 4.50000 -125.0 20.5 
2.5 2.71875 4.75000 -74.7 17.3 
3.0 4.00000 5.87500 46.9 4.0 
3.5 4.71875 7.12500 -51.0 -11.3 
4.0 3.00000 7.00000 -133.3 -53.0 
Figura 3.3 
Comparación de la solución verdadera con una solución numérica usando el método 
de Euler, para la integral de y' = -2X3 + 1 2X2 - 20x + 8.5 desde x = O hasta x = 4 con 
un tamaño de paso de 0.5. La condición inicial en x = O es y = 1.
Observe que aunque el cálculo capta la tendencia general de la solución verdadera, el 
error resulta considerable. Como se explica en la siguiente sección, es posible reducir 
tal error usando un tamaño de paso menor. 
El ejemplo anterior usa un polinomio simple como ecuación diferencial con el objetivo 
de facilitar el siguiente análisis de error. De esta forma, 
En efecto, un caso más general (y más común) implica EDO, donde aparece una 
función que depende tanto de como de , 
Conforme avancemos en esta parte del texto, nuestros ejemplos comprenderán EDO 
que dependen de variables independientes y dependientes. 
63
64 
3.2.2.- Diagrama de flujo 
Diagrama de Flujo Euler
65 
3.2.3.- Pseudocódigo 
‘ nt rva o nt grac ón 
xi = 0 
xf = 4 
‘var ab s n c a s 
x = xi 
y = 1 
‘ stab c tamaño paso t rm na 
‘ núm ro pasos cá c o 
dx = 0.5 
nc= (xf – xi) /dx 
‘con c on s sa a 
PRINT x,y 
´ciclo para implementar el método de Euler 
‘ sp g r s ta os 
DO i = 1, nc 
dydx = -2x3 +12x2 – 20x + 8.5 
y = y + dydx . dx 
x= x + dx 
PRINT x, y 
END DO
66 
3.2.4.- Programas en C 
EULER 
#include <iostream.h> 
#include <iomanip.h> 
#include <conio.h> 
#include <math.h> 
#include <stdlib.h> 
#include <dos.h> 
MAIN 
return (-2*pow(x,3))+(12*pow(x,2))-(20*x)+8.5; 
case EULER: Lee(x0,xf,y0,h); 
Euler(x0,xf,y0,h); 
getch(); 
break; 
case SALIR: gotoxy(34,20); 
cout<<"Fin de "<<__FILE__; 
gotoxy(34,21); 
cout<<"Espere un momento..."; 
sleep(1); 
exit(0); 
break; 
default: gotoxy(34,15); 
cout<<"Opcion no permitida"; 
getch(); 
break; 
} 
}while(op!=SALIR); 
return 0; 
} 
cout<<" METODO DE EULER "; 
gotoxy(10,4); 
cout<<"Xo = "<<setw(10)<<setprecision(5)<<x0; 
gotoxy(10,5); 
cout<<"Xf = "<<setw(10)<<setprecision(5)<<xf; 
gotoxy(10,6); 
cout<<"Yo = "<<setw(10)<<setprecision(5)<<y0; 
gotoxy(10,7); 
cout<<"h = "<<setw(10)<<setprecision(5)<<h; 
gotoxy(10,9); 
cout<<" x y"; 
gotoxy(9,10); 
cout<<"----------------------"; 
cout<<endl; 
cout<<setw(10) <<setprecision(5) << setiosflags(ios::fixed) << x; 
cout<<setw(20) <<setprecision(5) << setiosflags(ios::fixed) << y << endl; 
while(x<xf){ 
y+=h*f(x,y); 
x+=h; 
cout<<setw(10) <<setprecision(5) << setiosflags(ios::fixed) << x 
<<setw(20) <<setprecision(5) << setiosflags(ios::fixed) << y << 
endl; 
} 
} 
void Heun(float x0,float xf,float y0,float h) 
{
67 
3.2.5. - Demostración del programa
3.3.-Runge-Kutta 
El método de Runge-Kutta (RK) logra la exactitud del procedimiento de la serie 
Taylor sin necesitar el cálculo de derivadas de orden superior. Existen muchas 
variantes, pero todas tienen la forma generalizada de la siguiente ecuación. 
68 
(Ec.3.3) 
donde se conoce como la función incremento, la cual puede interpretarse 
como una pendiente representativa en el intervalo. La función incremento se escribe 
en forma general como 
(Ec.3.4) 
donde las son constantes y las son 
(Ec.3.4a) 
(Ec.3.4b) 
(Ec.3.4c) 
. 
. 
. 
(Ec.3.4d) 
donde las y son constantes. Observe que las son relaciones de recurrencia. 
Es decir, aparecen en la ecuación , la cual aparece en la ecuación , etcétera. 
Como cada es una evaluación funcional, esta recurrencia vuelve eficiente al método 
de RK para cálculos en computadora. 
Es posible tener varios tipos de métodos de Runge-Kutta empleando diferentes nú-meros 
de términos en la función incremento especificada por n. Observe que el 
método de Runge-Kutta (RK) de primer orden con n=1 es, de hecho, el método de 
Euler. Una vez que se elige n, se evalúan las a, p y q igualando la ecuación (Ec.3.3) a 
los términos en la expansión de la serie de Taylor. Así, al menos para las versiones 
de orden inferior, el número de términos, n, por lo común representa el orden de la 
aproximación. Por ejemplo, en la siguiente sección, los métodos RK de segundo 
orden usan la función incremento con dos términos (n – 2).
69 
MÉTODO DE RUNGE KUTTA DE SEGUNDO ORDEN 
La segunda versión de segundo orden de la ecuación (Ec.3.3) es 
(Ec.3.5) 
donde 
(Ec.3.5a) 
(Ec.3.5b) 
Como se describe a continuación, los valores de se evalúan al igualar 
la ecuación (Ec.3.5) con la expansión de la serie de Taylor hasta el término de 
segundo. 
3.3.1.- Ejemplo propuesto 
Comparación de varios esquemas RK de segundo orden 
Planteamiento del problema. Utilice el método de Runge Kutta para integrar 
numéricamente la siguiente ecuación: 
Con la condición inicial de que y = 1 en x = 0. Los valores aproximados se calcularon 
con el método RK de segundo orden, con un tamaño de paso de 0.5. 
RUNGE KUTTA DE SEGUNDO ORDEN 
0.0 1 
.0000 
0 
1.00000 0 
0.5 3.21875 3.277344 1.8 
1.0 3.00000 3.101563 3.4.. 
1.5 2.21875 2.347656 5.8 
2.0 2.00000 2.140625 7.0 
2.5 2.71875 2.855469 5.0 
3.0 4.00000 4.117188 2.9 
3.5 . 4.71875 4.800781 1.7 
4.0 3.00000 3.031250 1.0
70 
En el primer intervalo también es igual a 8.5 y 
La pendiente promedio se calcula mediante 
que se utiliza para predecir 
Resolver la siguiente función con la condición inicial en 
. Los valores aproximados se calcularon utilizando el método de runge kutta con un 
tamaño de paso igual a 1. 
0 2.0000000 2.0000000 0.00 2.0000000 0.00 
1 6.1946314 6.7010819 8.18 6.3608655 2.68 
2 14.8439219 16.3197819 9.94 15.3022367 3.09 
3 33.6771718 37.1992489 10.46 34.7432761 3.17 
4 75.3389626 83.3377674 10.62 77.7350962 3.18
71 
3.3.2.-Diagrama de flujo 
Diagrama de Flujo Runge Kutta
72 
3.3.3.- Pseudocódigo 
a) Programa pr nc pa o “man ja or” 
Asigna valores para 
n= número de ecuaciones 
yi= valores iniciales de n variables dependientes 
xi= valor inicial de la variable independiente 
xf= valor final de la variable independiente 
dx= cálculo del tamaño de paso 
xout= intervalo de salida 
x = xi 
m= 0 
xpm = x 
DO I = 1, n 
ypi,m = yi 
END DO 
DO 
xend = x + xout 
IF (xend xf) THEN xend = xf 
h= dx 
CALL Integrador (x, y, n, h, xend) 
m = m + 1 
xpm = x 
DO i = 1, n 
ypi,m = yi 
END DO 
IF (x xf) EXIT 
LOOP 
DISPLAY RESULTS 
END
73 
b) Rutina para tomar un paso de salida 
SUB integrator (x, y, n, h, xend) 
DO 
IF (xend – x < h) THEN h = xend – x 
CALL RK4 (x, y, n, h) 
IF (x xend) EXIT 
END DO 
END SUB 
c) Método RK de cuarto orden para un sistema de EDO 
SUB RK4(x, y, n, h) 
CALL Derivs (x, y, k1) 
DO i = 1, n 
ymi = yi + k1i * h / 2 
END DO 
CALL Derivs (x + h / 2, ym, k2) 
DO i = 1, n 
ymi = yi + k2i * h / 2 
END DO 
CALL Derivs (x + h / 2, ym, k3) 
DO i = 1, n 
yei = yi + k3i * h 
END DO 
CALL Derivs (x + h, ye, k4) 
DO i = 1, n 
slopei = (k1i + 2* (k2i+k3i)+k4i)/6 
yi = yi + slopei * h 
END DO 
x = x + h 
END SUB 
d) Rutina para determinar derivadas 
SUB Derivs (x, y, dy) 
dy1 = … 
dy2 = …. 
END SUB
74 
3.3.4.- Programas en C 
RUNGE KUTTA 
#include <iostream.h> 
#include <iomanip.h> 
#include <conio.h> 
#include <math.h> 
#include <stdlib.h> 
#include <dos.h> 
MAIN 
return 4*exp(0.8*x)-(0.5*y); 
case RK2: Lee(x0,xf,y0,h); 
Heun(x0,xf,y0,h); 
getch(); 
break; 
case SALIR: gotoxy(34,20); 
cout<<"Fin de "<<__FILE__; 
gotoxy(34,21); 
cout<<"Espere un momento..."; 
sleep(1); 
exit(0); 
break; 
default: gotoxy(34,15); 
cout<<"Opcion no permitida"; 
getch(); 
break; 
} 
}while(op!=SALIR); 
return 0; 
} 
cout<<"METODO DE HEUN (RK Orden 2)"<<endl; 
gotoxy(10,4); 
cout<<"Xo = "<< setw(10) << setprecision(5) <<x0; 
gotoxy(10,5); 
cout<<"Xf = "<< setw(10) << setprecision(5) <<xf; 
gotoxy(10,6); 
cout<<"Yo = "<< setw(10) << setprecision(5) <<y0; 
gotoxy(10,7); 
cout<<"h = "<< setw(10) << setprecision(5) <<h; 
gotoxy(10,9); 
cout<<"x y"; 
gotoxy(9,10); 
cout<<"----------------------"; 
cout<<endl; 
cout<<setw(10) << setprecision(5) << setiosflags(ios::fixed) << x; 
cout<<setw(20) << setprecision(5) << setiosflags(ios::fixed) << y <<endl; 
while(x<xf){ 
k1=h*f(x,y); 
k2=h*f(x+h,y+k1); 
y+=(k1/2.0+k2/2.0); 
x+=h; 
cout<<setw(10) << setprecision(5) << setiosflags(ios::fixed) << x 
<<setw(20) << setprecision(5) << setiosflags(ios::fixed) << y 
<<endl; 
} 
} 
void rk4(float x0,float xf,float y0,float h) 
{
75 
3.3.5.- Demostración del programa
4.- INTEGRACIÓN 
4.1.- Concepto y clasificación 
En este capítulo se abordará el tema clásico de integración definida. Para ello se 
utilizarán procesos finitos, en los que a diferencia de los métodos analíticos, donde 
el concepto de límite es central y por tanto los procesos infinitos se manejan 
conjuntos de puntos discretos y haremos pasar por ellos o entre ellos un polinomio, 
para después integrar o derivar dicho polinomio. Con esta técnica podremos 
integrar y derivar funciones dadas tabularmente o bien funciones analíticas muy 
complejas e, incluso, integrar aq é as c a nt gra “no st ”, como s n caso 
de 
76 
s n 
cos 
s n tc 
Además, dicha técnica se puede aproximar a la obtención de integrales dobles y 
triples. 
Siendo la derivada la medida de cambio puntual o instantáneo y la integral la suma 
o acumulación de tales cambios, resulta fundamental en cualquier actividad de in-geniería 
o ciencias, conocer ambas técnicas, y no menos importante, darle sentido 
físico a los resultados. 
4.2.- Simpson 1/3 
Una forma de obtener una estimación más exacta de una integral consiste en usar 
polinomios de grado superior para unir los puntos. Por ejemplo, si hay otro punto a 
la mitad entre y los tres puntos se pueden unir con una parábola (figura 
4.1a). Si hay dos puntos igualmente espaciados entre f(a) y f b , los cuatro puntos 
se pueden unir mediante un polinomio de tercer grado (figura 4.1b). Las fórmulas 
que resultan de tomar las integrales bajo esos polinomios se conocen como reglas 
de Simpson. 
La regla de Simpson 1/3 resulta cuando un polinomio de interpolación de segundo 
grado se sustituye en la siguiente ecuación: 
Figura 4.1a 
a) Descripción gráfica de la regla de Simpson 1/3, que consiste en tomar el 
área bajo una parábola que une tres puntos.
77 
Figura 4.1b 
b) Descripción gráfica de la regla de Simpson 3/8 que consiste en tomar el área 
bajo una ecuación cubica que une cuatro puntos. 
4.2.1.- Ejemplo propuesto 
Si se designan a y b como x0 y x2 respectivamente y f2(x) se representa por un 
polinomio de Lagrange de segundo grado, la integral se transforma en 
f 
f 
f 
Después de la integración y de las manipulaciones algebraicas, se obtiene la 
siguiente fórmula: 
f f f (Ec.4.1)
donde, en este caso, . Esta ecuación se conoce como regla de 
Simpson 1/3, y es la segunda fórmula de integración cerrada de Newton-Cotes. La 
especificación "1/3" se origina del hecho de que está dividida entre 3 en la 
ecuación (Ec.4.1). Una alternativa para obtenerla se integra el polinomio de Newton- 
Gregory para llegar a la misma fórmula. 
78 
La regla de Simpson 1/3 también se puede expresar usando el formato de la 
siguiente ecuación: 
a b f f f 
(Ec.4.2) 
Ancho Altura promedio 
donde a b y el punto a la mitad entre a y b , que está dado por 
(b+a)/2. Observe que, de acuerdo con la ecuación (Ec.4.2), el punto medio está 
ponderado por dos tercios; y los dos puntos extremos, por un sexto. 
Se puede demostrar que la aplicación a un solo segmento de la regla de Simpson 
1/3 tiene un error de truncamiento. 
t 
f 
o como 
t 
b a 
f 
(Ec.4.3) 
donde está en algún lugar en el intervalo de y Así, la regla de Simpson 1/3 
es más exacta que la regla del trapecio. No obstante, una comparación con la 
ecuación (21.6) indica que es más exacta de lo esperado. En lugar de ser 
proporcional a la tercera derivada, el error es proporcional a la cuarta derivada. Esto 
es porque, como se muestra en el cuadro 21.3, el término del coeficiente de tercer 
grado se hace cero durante la integración de la interpolación polinomial. En 
consecuencia, la regla de Simpson 1/3 alcanza una precisión de tercer orden aun 
cuando se base en sólo tres puntos.
79 
Aplicación simple de la regla de Simpson 1/3 
Planteamiento del problema. Con la ecuación (Ec.4.2) integre 
desde hasta . Recuerde que la integral exacta es 1.640533 
Solución. 
Por lo tanto, la ecuación (Ec.4.2.2) se utiliza para calcular 
Que representa un error exacto de 
que es aproximadamente 5 veces más precisa que una sola aplicación de la regla 
del trapecio 
El error estimado es [(Ec.4.2.2)] 
. 
donde -2400 es el promedio de la cuarta derivada en el intervalo, , debido a que el 
promedio de la cuarta derivada no es una estimación exacta de . Sin 
embargo, como este caso tiene que ver con un polinomio de quinto grado, el 
resultado concuerda.
80 
4.2.2.- Diagrama de flujo 
INICIO 
n_s, n_p, h, b, 
a, x_j, j, k, i 
Diagrama de Flujo Simpson 1/3
81 
4.2.3. - Pseudocódigo 
a) 
FUNCTION Simp13 (h, f0, fl, f2) 
simp13 = 2* h * (f0+4*f1+f2) /6 
END Simp13 
b) 
FUNCTION Simp38 (h, f0, fl, f2) 
simp38 = 3*h* (f0+3*(f1+f2)+f3) /8 
END Simp38 
c) 
FUNCION Simp13m (h, n, f) 
sum = f(0) 
DO i = 1, n- 2, 2 
sum = sum + 4 * fi + 2 * fi+1 
END DO 
sum = sum + 4 * fn-1 + 2 * fn 
simp13m = h * sum / 3 
END Simp13m 
d) 
FUNCTION SimpInt (a, b, n, f) 
h = (b – a) / n 
IF n = 1 THEN 
sum = trap (h, fn-1,fn) 
ELSE 
m = n 
odd = n / 2 – INT(n / 2) 
IF odd > 0 AND > 1 THEN 
sum = sum + simp38(h, fn-3, fn-2, fn-1, fn) 
m = n – 3 
END IF 
IF m > 1 THEN 
sum = sum + simp13m(h,m,f) 
END IF 
END IF 
SimpInt =sum 
END SimpInt
82 
4.2.4.- Programas en C 
#include <stdio.h> /*para printf(),scanf()*/ 
#include <conio.h> /*para getch(),clrscr()*/ 
#include <stdlib.h>/*para exit()*/ 
#include <dos.h> 
#include <math.h> 
#define NUMEL 20 
#define INTERVALOS 0 
float f(float); 
void _error(int n); 
MAIN 
} 
h=(b-a)/(2*n); 
S0=S1=0; 
for(i=1;i<=(2*n-1);++i){ 
x=a+((double)i)*h; 
if(!(i%2)) 
S0+=f(x); 
else 
S1+=f(x); 
} 
*Area=(h*(f(a)+4*S1+2*S0+f(b))/3.0); 
printf("n El area es -> %5.6f",*Area); 
getch(); 
} 
void LeeDatos(int opc) 
{ 
if(opc==SIMPSON1_3){ 
clrscr(); 
printf("n Metodo de Integracion por 1/3 de Simpson"); 
printf("n ========================================"); 
putchar('n'); 
printf("n Numero de intervalos (PAR) -> "); } 
scanf("%d",&n); 
if(n<1){ 
_error(INTERVALOS); 
exit(1); 
} 
else 
printf("n Valor de a =>"); 
scanf("%f",&a); 
printf("n Valor de b =>"); 
scanf("%f",&b); 
}
83 
4.2.5.- Demostración del programa
84 
COSTOS 
Para la elaboración de este manual de programas aplicados a métodos numéricos 
se recopiló información de diferentes fuentes: libros e internet pero como 
herramienta principal, el programa borland c++ versión 5.0 y el costo de operación 
de este software fue gratuito ya que la facultad cuenta con esta herramienta y está 
instalado en el centro de cómputo en nuestra facultad de ingeniería mecánica 
eléctrica.
CAPITULO III
APORTACIONES Y CONTRIBUCIONES AL DESARROLLO 
Una de las razones por la que se elaboró este manual, es para que el estudiante 
tenga como apoyo en la experiencia de métodos numéricos, programas para 
aplicar los métodos, brindándoles así una herramienta que podrán utilizar y les 
permitirá ahorrar tiempo y esfuerzo. 
Con este trabajo práctico educativo se pretende que al estudiante le sea de mucha 
utilidad y disponga de una herramienta más, principalmente a los estudiantes de 
ingeniería que cursen la experiencia educativa de métodos numéricos con el fin de 
que logre una mayor comprensión de los temas mencionados, utilizando como 
estrategia de aprendizaje el uso de programas que ayuden a agilizar el 
procedimiento de los métodos expuestos en este tema. 
86
87 
BIBLIOGRAFÍA 
MÉTODOS NUMÉRICOS PARA INGENIEROS CON PROGRAMAS DE 
APLICACIÓN 
STEVEN C. CHAPRA 
RAYMOND P. CANALE 
MÉTODOS NUMÉRICOS 
LUTHE OLVERA SCHUTZ 
MÉTODOS NUMÉRICOS APLICADOS A LA INGENIERÍA 
ANTONIO NIEVES
88 
ANEXOS 
Anexo A 
DIAGRAMAS DE FLUJO 
TERMINAL: 
Indica el inicio y el fin de un Diagrama de Flujo. 
DEFINICIÓN DE VARIABLES: 
Define todas y cada una de las variables que serán 
utilizadas en el programa representado en el diagrama 
de flujo. 
PROCESO: 
Cualquier tipo de operación que pueda originar cambio 
de valor, formato o posición de la información 
almacenada en memoria, operaciones aritméticas, de 
transferencia, etc. 
DECISIÓN: 
Indica operaciones lógicas o de comparación de datos, 
normalmente dos, y en función del resultado de la misma 
determina cual de los distintos caminos alternativos del 
programa se debe seguir; normalmente tiene dos salidas 
respuestas: sí o no, pero puede tener más según los 
casos. 
ENTRADA: 
Indica la asignación de un valor de una variable tomando 
este valor desde un dispositivo de entrada. 
SALIDA: 
Indica que el resultado será presentado ya sea por 
pantalla o por impresora.
89 
Anexo B 
CICLOS 
Ciclos: Son procesos repetitivos los cuales se ejecutan una o más instrucciones 
varias veces. 
Valor Inicial: Se encuentra asignado a una variable la cual es la que controla el 
ciclo y debe ser de tipo entero, además tiene el valor de inicio del ciclo. 
Valor Final: Con este valor indicamos la última vez que el ciclo debe ejecutarse. 
Incremento: Representa la frecuencia en que debe aumentarse la variable. 
Entrada: Marca el principio o reinicio de las instrucciones que se encuentran 
dentro del ciclo. 
Regreso: Indica donde termina el ciclo, en qué momento el proceso se repite. 
Salida: Indica la finalización de la ejecución de un ciclo.
90 
Anexo C 
PRINCIPIOS DE C 
En este anexo se ofrece una breve historia del desarrollo del lenguaje C y se 
consideran también sus características. 
ORÍGENES DEL C 
El proceso de desarrollo del lenguaje C se origina con la creación de un lenguaje 
llamado BCPL, que fue desarrollado por Martin Richards. El BCPL tuvo influencia 
en un lenguaje llamado B, el cual se usó en 1970 y fue inventado por Ken 
Thompson y que permitió el desarrollo de C en 1971, el cual lo inventó e 
implementó Dennis Ritchie. Para 1973 el sistema operativo UNIX estaba casi 
totalmente escrito en C. 
Durante muchos años el estándar para C fue la versión 5 del sistema operativo 
UNIX, documentada en ``The C Programming Language'' escrito por Brian W. 
Kernighan and Dennis M. Ritchie in 1978 comúnmente referido como K&R. 
Posteriormente se hicieron varias implementaciones las cuales mostraban las 
siguientes tendencias: 
Nuevas características 
Diferencias de máquinas 
Diferencias de productos 
Errores en los compiladores 
Malas implementaciones 
Esto originó que en el verano de 1983 se estableciera un comité para resolver 
estas discrepancias, el cual empezó a trabajar en un estándar ANSI C, la cual fue 
completada en 1988. 
CARACTERÍSTICAS DE C 
Algunas de las características más importantes que definen el lenguaje y que han 
permitido que sea tan popular, como lenguaje de programación son: 
Tamaño pequeño. 
Uso extensivo de llamadas a funciones. 
Comandos breves (poco tecleo). 
Lenguaje estructurado. 
Programación de bajo nivel (nivel bit) 
Implementación de apuntadores - uso extensivo de apuntadores para la memoria, 
arreglos, estructuras y funciones 
Las diversas razones por la cual se ha convertido en un lenguaje de uso 
profesional son: 
El uso de constructores de alto nivel. 
El poder manejar actividades de bajo-nivel. 
El generar programas eficientes. 
La posibilidad de poder ser compilado en una variedad de computadoras, con
pocos cambios (portabilidad). 
Un punto en contra es que tiene una detección pobre de errores, lo cual en 
ocasiones es problemático para los principiantes. 
Estructura de un programa en C 
Un programa de C tiene básicamente la siguiente forma: 
Comandos del preprocesador. 
Definiciones de tipos. 
Prototipos de funciones - declara el tipo de función y las variables pasadas a la 
misma. 
Variables 
Funciones 
Para un programa se debe tener una función main(). 
Una función tiene la forma: 
tipo nombre_de_la_funcion (parámetros) 
{ 
91 
variables locales 
sentencias de C 
} 
Si la definición del tipo es omitida, C asume que la función regresa un tipo entero. 
Nota: Lo anterior puede ser una fuente de problemas en un programa. 
A continuación se muestra un primer programa: 
/* Programa ejemplo */ 
main() 
{ 
printf( "Me gusta Cn" ); 
exit (0); 
} 
NOTAS: 
C requiere un punto y coma al final de cada sentencia. 
printf es una función estándar de C, la cual es llamada en la función main(). 
n significa salto de línea. Salida formateada. 
exit() es también una función estándar que hace que el programa termine. En el 
sentido estricto no es necesario ya que es la última línea de main() y de cualquier 
forma terminará el programa. 
En caso de que se hubiera llamado a la función printf de la siguiente forma: 
printf(".n.1n..2n...3n"); 
La salida tendría la siguiente forma: 
.1 
..2 
...3
92 
VARIABLES 
C tiene los siguientes tipos de datos simples: 
Tabla: Tipos de C 
Tipo Tamaño (bytes) Límite inferior Límite superior 
Char 1 -- -- 
unsigned char 1 
short int 2 
unsigned short int 2 
(long) int 4 
Float 4 
double 8 
Los tipos de datos básicos tiene varios modificadores que les preceden. Se usa un 
modificador para alterar el significado de un tipo base para que encaje con las 
diversas necesidades o situaciones. Los modificadores son: signed, unsigned, long 
y short. 
En los sistemas UNIX todos los tipos int son long int, a menos que se especifique 
explícitamente short int. 
Nota: no hay un tipo booleano en C -- se deberá usar char, int o aún mejor 
unsigned char. 
signed, unsigned, long y short pueden ser usados con los tipos char e int. Aunque 
es permitido el uso de signed en enteros, es redundante porque la declaración de 
entero por defecto asume un número con signo. 
Para declarar una variable en C, se debe seguir el siguiente formato: 
tipo lista_variables; 
tipo es un tipo válido de C y lista_variables puede consistir en uno o más 
identificadores separados por una coma. Un identificador debe comenzar con una 
letra o un guión bajo. 
Ejemplo: 
int i, j, k; 
float x,y,z; 
char ch;
93 
DEFINICIÓN DE VARIABLES GLOBALES 
Una variable global se declara fuera de todas las funciones, incluyendo a la función 
main(). Una variable global puede ser utilizada en cualquier parte del programa. 
Por ejemplo: 
short numero, suma; 
int numerogr, sumagr; 
char letra; 
main() 
{ 
... 
} 
Es también posible pre inicializar variables globales usando el operador de 
asignación =, por ejemplo: 
float suma= 0.0; 
int sumagr= 0; 
char letra= 'A'; 
main() 
{ 
... 
} 
Que es lo mismo que: 
float suma; 
int sumagr; 
char letra; 
main() 
{ 
suma = 0.0; 
sumagr= 0; 
letra = 'A'; 
... 
} 
Dentro de C también se permite la asignación múltiple usando el operador =, por 
ejemplo: 
a = b = c = d = 3; 
...que es lo mismo, pero más eficiente que: 
a = 3; 
b = 3; 
c = 3;
94 
d = 3; 
La asignación múltiple se puede llevar a cabo, si todos los tipos de las variables 
son iguales. 
Se pueden redefinir los tipos de C usando typedef. Como un ejemplo de un simple 
uso se considera como se crean dos nuevos tipos real y letra. Estos nuevos tipos 
pueden ser usados de igual forma como los tipos predefinidos de C. 
typedef float real; 
typedef char letra; 
/* Declaración de variables usando el nuevo tipo */ 
real suma=0.0; 
letra sig_letra; 
LECTURA Y ESCRITURA DE VARIABLES 
El lenguaje C usa salida formateada. La función printf tiene un carácter especial 
para formatear (%) -- un carácter enseguida define un cierto tipo de formato para 
una variable. 
%c caracteres 
%s cadena de caracteres 
%d enteros 
%f flotantes 
Por ejemplo: 
printf("%c %d %f",ch,i,x); 
La sentencia de formato se encierra entre " ", y enseguida las variables. 
Asegurarse que el orden de formateo y los tipos de datos de las variables 
coincidan. 
scanf() es la función para entrar valores a variables. Su formato es similar a printf. 
Por ejemplo: 
scanf("%c %d %f %s",&ch, &i, &x, cad); 
Observar que se antepone & a los nombres de las variables, excepto a la cadena 
de caracteres. 
CONSTANTES 
ANSI C permite declarar constantes. Cuando se declara una constante es un poco 
parecido a declarar una variable, excepto que el valor no puede ser cambiado. 
La palabra clave const se usa para declarar una constante, como se muestra a 
continuación: 
const a = 1; 
int a = 2; 
Notas: 
Se puede usar constantes o después del tipo.
Es usual inicializar una constante con un valor, ya que no puede ser cambiada de 
alguna otra forma. 
La directiva del preprocesador #define es un método más flexible para definir 
constantes en un programa. 
Frecuentemente se ve la declaración const en los parámetros de la función. Lo 
anterior simplemente indica que la función no cambiara el valor del parámetro. Por 
ejemplo, la siguiente función usa este concepto: 
char *strcpy(char *dest, const char *orig); 
El segundo argumento orig es una cadena de C que no será alterada, cuando se 
use la función de la biblioteca para copiar cadenas. 
95 
OPERADORES ARITMÉTICOS 
Lo mismo que en otros lenguajes de programación, en C se tienen los operadores 
aritméticos más usuales (+ suma, - resta, * multiplicación, / división y % módulo). 
El operador de asignación es =, por ejemplo: i=4; ch='y'; 
Incremento ++ y decremento -- unario. Los cuales son más eficientes que las 
respectivas asignaciones. Por ejemplo: x++ es más rápido que x=x+1. 
Los operadores ++ y -- pueden ser prefijos o postfijos. Cuando son prefijos, el valor 
es calculado antes de que la expresión sea evaluada, y cuando es postfijo el valor 
es calculado después que la expresión es evaluada. 
En el siguiente ejemplo, ++z es prefijo y -- es postfijo: 
int x,y,z; 
main() 
{ 
x=( ( ++z ) - ( y-- ) ) % 100; 
} 
Que es equivalente a: 
int x,y,z; 
main() 
{ 
z++; 
x = ( z-y ) % 100; 
y--; 
} 
El operador % (módulo o residuo) solamente trabaja con enteros, aunque existe 
una función para flotantes. 
El operador división / es para división entera y flotantes. Por lo tanto hay que tener 
cuidado. El resultado de x = 3 / 2; es uno, aún si x es declarado como float. La 
regla es: si ambos argumentos en una división son enteros, entonces el resultado 
es entero. Si se desea obtener la división con la fracción, entonces escribirlo como: 
x = 3.0 / 2; o x = 3 / 2.0 y aún mejor x = 3.0 / 2.0. 
Por otra parte, existe una forma más corta para expresar cálculos en C. Por 
ejemplo, si se tienen expresiones como: i = i + 3; o x = x * (y + 2); , pueden ser
96 
reescritas como: 
Lo cual es equivalente, pero menos eficiente que: 
Por lo que podemos reescribir las expresiones anteriores como: i += 3; y x *= y + 2; 
respectivamente. 
OPERADORES DE COMPARACIÓN 
El operador para probar la igualdad es ==, por lo que se deberá tener cuidado de 
no escribir accidentalmente sólo =, ya que: 
if ( i = j ) ... 
Es una sentencia legal de C (sintácticamente hablando aunque el compilador avisa 
cuando se emplea), la cual copia el valor de ``j'' en ``i'', lo cual será interpretado 
como VERDADERO, si j es diferente de cero. 
Diferente es !=, otros operadores son: < menor que, > mayor que, <= menor que o 
igual a y >= (mayor que o igual a). 
OPERADORES LÓGICOS 
Los operadores lógicos son usualmente usados con sentencias condicionales o 
relacionales, los operadores básicos lógicos son: 
&& Y lógico, || O lógico y! negación. 
ORDEN DE PRECEDENCIA 
Es necesario ser cuidadosos con el significado de expresiones tales como a + b * 
c, dependiendo de lo que se desee hacer 
(a + b) * c 
o 
a + (b * c) 
Todos los operadores tienen una prioridad, los operadores de mayor prioridad son 
evaluados antes que los que tienen menor prioridad. Los operadores que tienen la 
misma prioridad son evaluados de izquierda a derecha, por lo que: 
a - b - c 
es evaluado como 
(a - b) - c 
Prioridad Operador(es) 
Más alta ( ) [ ] -> 
! ~ ++ -- - (tipo) * & sizeof 
* / % 
+ -
97 
<< >> 
< <= > >= 
== != 
& 
^ 
| 
&& 
|| 
? 
= += -= *= /= 
Más baja , 
De acuerdo a lo anterior, la siguiente expresión: 
a < 10 && 2 * b < c 
Es interpretada como: 
(a < 10) && ( (2 * b) < c ) 
y 
a = 
b = 
10 / 5 
+ 2; 
como 
a = 
( b = 
( 10 / 5 ) 
+ 2 ); 
ESTRUCTURAS CONDICIONALES 
En este capítulo se revisan los distintos métodos con los que C controla el flujo 
lógico de un programa. 
Como se revisó en el capítulo anterior, los operadores relaciones binarios que se 
usan son: 
==, !=, <, <=, > y >= 
además los operadores lógicos binarios: 
||, && 
y el operador lógico unario de negación !, que sólo toma un argumento. 
Los operadores anteriores son usados con las siguientes estructuras que se 
muestran.
98 
LA SENTENCIA IF 
Las tres formas como se puede emplear la sentencia if son: 
if (condición) 
sentencia; 
...o 
if (condición) 
sentencia1; 
else 
sentencia2; 
...o 
if (condicion1) 
sentencia1; 
else if (condicion2) 
sentencia2; 
... 
else 
sentencian; 
El flujo lógico de esta estructura es de arriba hacia abajo. La primera sentencia se 
ejecutará y se saldrá de la estructura if si la primera condición es verdadera. Si la 
primera condición fue falsa, y existe otra condición, se evalúa, y si la condición es 
verdadera, entonces se ejecuta la sentencia asociada. Si existen más condiciones 
dentro de la estructura if, se van evaluando éstas, siempre y cuando las 
condiciones que le precedan sean falsas. 
La sentencia que está asociada a la palabra reservada else, se ejecuta si todas las 
condiciones de la estructura if fueron falsas. 
Por ejemplo: 
main() 
{ 
int x, y, w; 
........ 
if (x>0) 
{ 
z=w; 
....... 
} 
else 
{ 
z=y; 
....... 
} 
}
99 
EL OPERADOR “?” 
El operador ternario condicional “?” es más eficiente que la sentencia if. El 
operador ? tiene el siguiente formato: 
expresión1 ? expresión 2 : expresion3; 
Que es equivalente a la siguiente expresión: 
if (expresión1) then expresión2 else expresión3; 
Por ejemplo, para asignar el máximo de a y b a la variable z, usando ?, 
tendríamos: 
z = (a>b) ? a : b; 
que es lo mismo que: 
if (a > b) 
z = a; 
else 
z = b; 
El uso del operador “?” para reemplazar las sentencias if ... else no se restringe 
sólo a asignaciones, como en el ejemplo anterior. Se pueden ejecutar una o más 
llamadas de función usando el operador ? poniéndolas en las expresiones que 
forman los operandos, como en el ejemplo siguiente: 
f1(int n) 
{ 
printf("%d ",n); 
} 
f2() 
{ 
printf("introducidon"); 
} 
main() 
{ 
int t; 
printf(": "); 
scanf("%d",&t); 
/* imprime mensaje apropiado */ 
t ? f1(t) + f2() : printf("Se dio un ceron"); 
}
100 
LA SENTENCIA SWITCH 
Aunque con la estructura if ... else if se pueden realizar comprobaciones múltiples, 
en ocasiones no es muy elegante, ya que el código puede ser difícil de seguir y 
puede confundir incluso al autor transcurrido un tiempo. Por lo anterior, C tiene 
incorporada una sentencia de bifurcación múltiple llamada switch. Con esta 
sentencia, la computadora comprueba una variable sucesivamente frente a una 
lista de constantes enteras o de carácter. Después de encontrar una coincidencia, 
la computadora ejecuta la sentencia o bloque de sentencias que se asocian con la 
constante. La forma general de la sentencia switch es: 
switch (variable) { 
case constante1: 
secuencia de sentencias 
break; 
case constante2: 
secuencia de sentencias 
break; 
case constante3: 
secuencia de sentencias 
break; 
... 
default: 
secuencia de sentencias 
} 
Donde la computadora ejecuta la sentencia default si no coincide ninguna 
constante con la variable, esta última es opcional. Cuando se encuentra una 
coincidencia, la computadora ejecuta las sentencias asociadas con el case hasta 
encontrar la sentencia break con lo que sale de la estructura switch. 
Las limitaciones que tiene la sentencia switch ... case respecto a la estructura if 
son: 
Sólo se tiene posibilidad de revisar una sola variable. 
Con switch sólo se puede comprobar por igualdad, mientras que con if puede ser 
con cualquier operador relacional. 
No se puede probar más de una constante por case. 
La forma como se puede simular el último punto, es no teniendo sentencias 
asociados a un case, es decir, teniendo una sentencia nula donde sólo se pone el 
caso, con lo que se permite que el flujo del programa caiga al omitir las sentencias, 
como se muestra a continuación: 
switch (letra) 
{ 
case 'a': 
case 'e': 
case 'i': 
case 'o': 
case 'u': 
numvocales++; 
break;
101 
case ' ': 
numesp++; 
break; 
default: 
numotras++; 
break; 
} 
ITERACIÓN 
En este capítulo se revisan los mecanismos de C para repetir un conjunto de 
instrucciones hasta que se cumple cierta condición. 
LA SENTENCIA FOR 
La sentencia for tiene el siguiente formato: 
for ( expresión1; expresión2; expresión3) 
sentencia; 
o { bloque de sentencias } 
En donde expresión1 se usa para realizar la inicialización de variables, usando una 
o varias sentencias, si se usan varias sentencias deberá usarse el operador, para 
separarlas. Por lo general, establece el valor de la variable de control del ciclo. 
expresión2 se usa para la condición de terminación del ciclo y expresión3 es el 
modificador a la variable de control del ciclo cada vez que la computadora lo repite, 
pero también puede ser más que un incremento. 
Por ejemplo: 
int X; 
main() 
{ 
for( X=3; X>0; X--) 
{ 
printf("X=%dn",X); 
} 
} 
genera la siguiente salida a pantalla ... 
X=3 
X=2 
X=1
Todos las siguientes sentencias for son válidas en C. Las aplicaciones prácticas de 
tales sentencias no son importantes aquí, ya que tan sólo se intenta ilustrar 
algunas características que pueden ser de utilidad: 
for ( x=0; ( (x>3) && (x<9) ); x++ ) 
102 
for ( x=0, y=4; ( (x>3) && (x<9) ); x++, y+=2) 
for ( x=0, y=4, z=4000; z; z/=10) 
En el segundo ejemplo se muestra la forma como múltiples expresiones pueden 
aparecer, siempre y cuando estén separadas por una coma , 
En el tercer ejemplo, el ciclo continuará iterando hasta que z se convierta en . 
LA SENTENCIA WHILE 
La sentencia while es otro ciclo o bucle disponible en C. Su formato es: 
while ( expresión) sentencia; 
donde sentencia puede ser una sentencia vacía, una sentencia única o un bloque 
de sentencias que se repetirán. Cuando el flujo del programa llega a esta 
instrucción, primero se revisa si la condición es verdad para ejecutar la(s) 
sentencia(s), y después el ciclo while se repetirá mientras la condición sea 
verdadera. Cuando llega a ser falsa, el control del programa pasa a la línea que 
sigue al ciclo. 
En el siguiente ejemplo se muestra una rutina de entrada desde el teclado, la cual 
se cicla mientras no se pulse A: 
main() 
{ 
char carac; 
carac = '0'; 
while( carac != 'A') carac = getchar(); 
} 
Antes de entrar al ciclo se inicializa la variable carac a nulo. Después pasa a la 
sentencia while donde se comprueba si carac no es igual a 'A', como sea verdad 
entonces se ejecuta la sentencia del bucle (carac = getchar();). La función getchar() 
lee el siguiente carácter del flujo estándar (teclado) y lo devuelve, que en nuestro 
ejemplo es el caracter que haya sido tecleado. Una vez que se ha pulsado una 
tecla, se asigna a carac y se comprueba la condición nuevamente. Después de 
pulsar A, la condición llega a ser falsa porque carac es igual a A, con lo que el ciclo 
termina. 
De lo anterior, se tiene que tanto el ciclo for, como el ciclo while comprueban la 
condición en lo alto del ciclo, por lo que el código dentro del ciclo no se ejecuta 
siempre.
103 
A continuación mostramos otro ejemplo: 
main() 
{ 
int x=3; 
while( x>0 ) 
{ 
printf("x = %dn", x); 
x--; 
} 
} 
que genera la siguiente salida en pantalla: 
x = 3 
x = 2 
x = 1 
Como se observa, dentro del ciclo tenemos más de una sentencia, por lo que se 
requiere usar la llave abierta y la llave cerrada { ... } para que el grupo de 
sentencias sean tratadas como una unidad. 
Como el ciclo while pueda aceptar también expresiones, y no solamente 
condiciones lo siguiente es válido: 
while ( x-- ); 
while ( x = x + 1 ); 
while ( x += 5 ); 
Si se usan este tipo de expresiones, solamente cuando el resultado de x--, x=x+1 o 
x+=5 sea cero, la condición fallará y se podrá salir del ciclo. 
De acuerdo a lo anterior, podemos realizar una operación completa dentro de la 
expresión. Por ejemplo: 
main() 
{ 
char carac; 
carac = '0'; 
while ( (carac = getchar()) != 'A' ) 
putchar(carac); 
} 
En este ejemplo se usan las funciones de la biblioteca estándar getchar() -- lee un 
carácter del teclado y putchar() escribe un carácter dado en pantalla. El ciclo while 
procederá a leer del teclado y lo mostrará hasta que el carácter A sea leído. 
LA SENTENCIA DO-WHILE 
Al contrario de los ciclos for y while que comprueban la condición en lo alto del 
bucle, el bucle do ... while la examina en la parte baja del mismo. Esta 
característica provoca que un ciclo do ... while siempre se ejecute al menos una
104 
vez. La forma general del ciclo es: 
do { 
sentencia; 
} while (condición); 
Aunque no son necesarias las llaves cuando sólo está presente una sentencia, se 
usan normalmente por legibilidad y para evitar confusión (respecto al lector, y no 
del compilador) con la sentencia while. 
En el siguiente programa se usa un ciclo do ... while para leer números desde el 
teclado hasta que uno de ellos es menor que o igual a 100: 
main() 
{ 
int num; 
do 
{ 
scanf("%d", &num); 
} while ( num>100 ); 
} 
Otro uso común de la estructura do... while es una rutina de selección en un menú, 
ya que siempre se requiere que se ejecute al menos una vez. 
main() 
{ 
int opc; 
printf("1. Derivadasn"); 
printf("2. Limitesn"); 
printf("3. Integralesn"); 
do 
{ 
printf(" Teclear una opcion: "); 
scanf("%d", &opc); 
switch(opc) 
{ 
case 1: 
printf("tOpcion 1 seleccionadann"); 
break; 
case 2: 
printf("tOpcion 2 seleccionadann"); 
break; 
case 3: 
printf("tOpcion 3 seleccionadann"); 
break; 
default: 
printf("tOpcion no disponiblenn"); 
break; 
}
105 
} while( opc != 1 && opc != 2 && opc != 3); 
} 
Se muestra un ejemplo donde se reescribe usando do... while uno de los ejemplos 
ya mostrados. 
main() 
{ 
int x=3; 
do 
{ 
printf("x = %dn", x--); 
} 
while( x>0 ) ; 
} 
USO DE BREAK Y CONTINUE 
Como se comento uno de los usos de la sentencia break es terminar un case en la 
sentencia switch. Otro uso es forzar la terminación inmediate de un ciclo, saltando 
la prueba condicional del ciclo. 
Cuando se encuentra la sentencia break en un bucle, la computadora termina 
inmediatamente el ciclo y el control del programa pasa a la siguiente sentencia del 
ciclo. Por ejemplo: 
main() 
{ 
int t; 
for(t=0; t<100; t++) 
{ 
printf("%d ", t); 
if (t==10) break; 
} 
} 
Este programa muestra en pantalla los números del 0 al 10, cuando alcanza el 
valor 10 se cumple la condición de la sentencia if, se ejecuta la sentencia break y 
sale del ciclo. 
La sentencia continue funciona de manera similar a la sentencia break. Sin 
embargo, en vez de forzar la salida, continue fuerza la siguiente iteración, por lo 
que salta el código que falta para llegar a probar la condición. Por ejemplo, el 
siguiente programa visualizará sólo los números pares: 
main() 
{ 
int x; 
for( x=0; x<100; x++) 
{ 
if (x%2) 
continue; 
printf("%d ",x);
106 
} 
} 
Finalmente se considera el siguiente ejemplo donde se leen valores enteros y se 
procesan de acuerdo a las siguientes condiciones. Si el valor que sea leído es 
negativo, se desea imprimir un mensaje de error y se abandona el ciclo. Si el valor 
es mayor que 100, se ignora y se continúa leyendo, y si el valor es cero, se desea 
terminar el ciclo. 
main() 
{ 
int valor; 
while( scanf("%d", &valor) == 1 && valor != 0) 
{ 
if ( valor<0 ) 
{ 
printf("Valor no validon"); 
break; 
/* Salir del ciclo */ 
} 
if ( valor>100) 
{ 
printf("Valor no validon"); 
continue; 
/* Pasar al principio del ciclo nuevamente */ 
} 
printf("Se garantiza que el valor leido esta entre 1 y 100"); 
} 
} 
ARREGLOS UNIDIMENSIONALES Y MULTIDIMENSIONALES 
Los arreglos son una colección de variables del mismo tipo que se referencian 
utilizando un nombre común. Un arreglo consta de posiciones de memoria 
contigua. La dirección más baja corresponde al primer elemento y la más alta al 
último. Un arreglo puede tener una o varias dimensiones. Para acceder a un 
elemento en particular de un arreglo se usa un índice. 
El formato para declarar un arreglo unidimensional es: 
tipo nombre_arr [ tamaño ] 
Por ejemplo, para declarar un arreglo de enteros llamado listanum con diez 
elementos se hace de la siguiente forma: 
int listanum[10]; 
En C, todos los arreglos usan cero como índice para el primer elemento. Por tanto, 
el ejemplo anterior declara un arreglo de enteros con diez elementos desde 
listanum[0] hasta listanum[9]. 
La forma como pueden ser accesados los elementos de un arreglo, es de la 
siguiente forma:
107 
listanum[2] = 15; /* Asigna 15 al 3er elemento del arreglo listanum*/ 
num = listanum[2]; /* Asigna el contenido del 3er elemento a la variable num */ 
El lenguaje C no realiza comprobación de contornos en los arreglos. En el caso de 
que sobrepase el final durante una operación de asignación, entonces se 
asignarán valores a otra variable o a un trozo del código, esto es, si se dimensiona 
un arreglo de tamaño N, se puede referenciar el arreglo por encima de N sin 
provocar ningún mensaje de error en tiempo de compilación o ejecución, incluso 
aunque probablemente se provoque el fallo del programa. Como programador se 
es responsable de asegurar que todos los arreglos sean lo suficientemente 
grandes para guardar lo que pondrá en ellos el programa. 
C permite arreglos con más de una dimensión, el formato general es: 
tipo nombre_arr [ tam1 ][ tam2 ] ... [ tamN]; 
Por ejemplo un arreglo de enteros bidimensionales se escribirá como: 
int tabladenums[50][50]; 
Observar que para declarar cada dimensión lleva sus propios paréntesis 
cuadrados. 
Para acceder los elementos se procede de forma similar al ejemplo del arreglo 
unidimensional, esto es, 
tabladenums[2][3] = 15; /* Asigna 15 al elemento de la 3ª fila y la 4ª columna*/ 
num = tabladenums[25][16]; 
A continuación se muestra un ejemplo que asigna al primer elemento de un arreglo 
bidimensional cero, al siguiente 1, y así sucesivamente. 
main() 
{ 
int t,i,num[3][4]; 
for(t=0; t<3; ++t) 
for(i=0; i<4; ++i) 
num[t][i]=(t*4)+i*1; 
for(t=0; t<3; ++t) 
{ 
for(i=0; i<4; ++i) 
printf("num[%d][%d]=%d ", t,i,num[t][i]); 
printf("n"); 
} 
} 
En C se permite la inicialización de arreglos, debiendo seguir el siguiente formato: 
tipo nombre_arr[ tam1 ][ tam2 ] ... [ tamN] = {lista-valores}; 
Por ejemplo: 
int i[10] = {1,2,3,4,5,6,7,8,9,10}; 
int num[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
108 
CADENAS 
A diferencia de otros lenguajes de programación que emplean un tipo denominado 
cadena string para manipular un conjunto de símbolos, en C, se debe simular 
mediante un arreglo de caracteres, en donde la terminación de la cadena se debe 
indicar con nulo. Un nulo se especifica como '0'. Por lo anterior, cuando se declare 
un arreglo de caracteres se debe considerar un carácter adicional a la cadena más 
larga que se vaya a guardar. Por ejemplo, si se quiere declarar un arreglo cadena 
que guarde una cadena de diez caracteres, se hará como: 
char cadena[11]; 
Se pueden hacer también inicializaciones de arreglos de caracteres en donde 
automáticamente C asigna el carácter nulo al final de la cadena, de la siguiente 
forma: 
char nombre_arr[ tam ]="cadena"; 
Por ejemplo, el siguiente fragmento inicializa cadena con ``hola'': 
char cadena[5]="hola"; 
El código anterior es equivalente a: 
char cadena[5]={'h','o','l','a','0'}; 
Para asignar la entrada estándar a una cadena se puede usar la función scanf con 
la opción %s (observar que no se requiere usar el operador &), de igual forma para 
mostrarlo en la salida estándar. 
Por ejemplo: 
main() 
{ 
char nombre[15], apellidos[30]; 
printf("Introduce tu nombre: "); 
scanf("%s",nombre); 
printf("Introduce tus apellidos: "); 
scanf("%s",apellidos); 
printf("Usted es %s %sn",nombre,apellidos); 
} 
El lenguaje C no maneja cadenas de caracteres, como se hace con enteros o 
flotantes, por lo que lo siguiente no es válido: 
main() 
{ 
char nombre[40], apellidos[40], completo[80]; 
nombre="José María"; /* Ilegal */ 
apellidos="Morelos y Pavón"; /* Ilegal */ 
completo="Gral."+nombre+apellidos; /* Ilegal */ 
} 
Funciones 
Una función es un conjunto de declaraciones, definiciones, expresiones y 
sentencias que realizan una tarea específica.
109 
El formato general de una función en C es: 
especificador_de_tipo nombre_de_función( lista_de_parámetros ) 
{ 
variables locales 
código de la función 
} 
El especificador_de_tipo indica el tipo del valor que la función devolverá mediante 
el uso de return. El valor puede ser de cualquier tipo válido. Si no se específica un 
valor, entonces la computadora asume por defecto que la función devolverá un 
resultado entero. No se tienen siempre que incluir parámetros en una función. la 
lista de parámetros puede estar vacía. 
Las funciones terminan y regresan automáticamente al procedimiento que las 
llamó cuando se encuentra la última llave}, o bien, se puede forzar el regreso antes 
usando la sentencia return. Además del uso señalado la función return se usa para 
devolver un valor. 
Se examina a continuación un ejemplo que encuentra el promedio de dos enteros: 
float encontprom(int num1, int num2) 
{ 
float promedio; 
promedio = (num1 + num2) / 2.0; 
return(promedio); 
} 
main() 
{ 
int a=7, b=10; 
float resultado; 
resultado = encontprom(a, b); 
printf("Promedio=%fn",resultado); 
} 
FUNCIONES VOID 
Las funciones void dan una forma de emular, lo que en otros lenguajes se conocen 
como procedimientos (por ejemplo, en PASCAL). Se usan cuando no requiere 
regresar un valor. Se muestra un ejemplo que imprime los cuadrados de ciertos 
números. 
void cuadrados() 
{ 
int contador; 
for( contador=1; contador<10; contador++) 
printf("%dn",contador*contador); 
} 
main() 
{
110 
cuadrados(); 
} 
En la función cuadrados no está definido ningún parámetro, y por otra parte 
tampoco se emplea la sentencia return para regresar de la función. 
FUNCIONES Y ARREGLOS 
Cuando se usan un arreglo como un argumento a la función, se pasa sólo la 
dirección del arreglo y no la copia del arreglo entero. Para fines prácticos podemos 
considerar el nombre del arreglo sin ningún índice como la dirección del arreglo. 
Considerar el siguiente ejemplo en donde se pasa un arreglo a la función imp_rev, 
observar que no es necesario especificar la dimensión del arreglo cuando es un 
parámetro de la función. 
void imp_rev(char s[]) 
{ 
int t; 
for( t=strlen(s)-1; t>=0; t--) 
printf("%c",s[t]); 
} 
main() 
{ 
char nombre[]="Facultad"; 
imp_rev(nombre); 
} 
Observar que en la función imp_rev se usa la función strlen para calcular la 
longitud de la cadena sin incluir el terminador nulo. Por otra parte, la función 
imp_rev no usa la sentencia return ni para terminar de usar la función, ni para 
regresar algún valor. 
Se muestra otro ejemplo, 
float enconprom(int tam, float lista[]) 
{ 
int i; 
float suma = 0.0; 
for ( i=0; i<tam; i++) 
suma += lista[i]; 
return(suma/tam); 
} 
main() 
{ 
float numeros[]={2.3, 8.0, 15.0, 20.2, 44.01, -3.0, -2.9}; 
printf("El promedio de la lista es %fn", enconprom(7,numeros) ); 
}
Badillo riosyortizdelaluz

Recomendados

Método numérico - regla de simpson por
Método numérico  - regla de simpsonMétodo numérico  - regla de simpson
Método numérico - regla de simpsonJoe Arroyo Suárez
50K vistas40 diapositivas
MéTodo De IteracióN De Punto Fijo por
MéTodo De IteracióN De Punto FijoMéTodo De IteracióN De Punto Fijo
MéTodo De IteracióN De Punto Fijolisset neyra
42.8K vistas6 diapositivas
Ejercicios jacobi por
Ejercicios jacobiEjercicios jacobi
Ejercicios jacobidjp951
40.2K vistas22 diapositivas
Aplicaciones de las ecuaciones diferenciales por
Aplicaciones de las ecuaciones diferenciales Aplicaciones de las ecuaciones diferenciales
Aplicaciones de las ecuaciones diferenciales Ingeniero Edwin Torres Rodríguez
90.9K vistas25 diapositivas
Metodos numericos con matlab por
Metodos numericos con matlabMetodos numericos con matlab
Metodos numericos con matlabFlor Cardenas Alvarez
30.9K vistas163 diapositivas
Metodo de simpsons y de los trapecios por
Metodo de simpsons y de los trapeciosMetodo de simpsons y de los trapecios
Metodo de simpsons y de los trapeciosFranklin Gualán
53K vistas17 diapositivas

Más contenido relacionado

La actualidad más candente

ejercicios-resueltos-interpolacion-polinomial por
ejercicios-resueltos-interpolacion-polinomialejercicios-resueltos-interpolacion-polinomial
ejercicios-resueltos-interpolacion-polinomialNovato de la Weeb Fox Weeb
7.1K vistas6 diapositivas
Ejemplo del Método de Falsa Posición por
Ejemplo del Método de Falsa PosiciónEjemplo del Método de Falsa Posición
Ejemplo del Método de Falsa PosiciónDaniela Medina
26K vistas5 diapositivas
Integracion numerica 1_trapecio por
Integracion numerica 1_trapecioIntegracion numerica 1_trapecio
Integracion numerica 1_trapeciofe0102036
1.9K vistas8 diapositivas
Metodo adams bashforth por
Metodo adams bashforthMetodo adams bashforth
Metodo adams bashforthSilvanita Serrano Armijos
9.3K vistas7 diapositivas
“método de euler y runge kutta” por
“método de euler y runge kutta”“método de euler y runge kutta”
“método de euler y runge kutta”Astorgo
1.7K vistas12 diapositivas
Algoritmos para matlab por
Algoritmos para matlabAlgoritmos para matlab
Algoritmos para matlabVitoto96
38.5K vistas24 diapositivas

La actualidad más candente(20)

Ejemplo del Método de Falsa Posición por Daniela Medina
Ejemplo del Método de Falsa PosiciónEjemplo del Método de Falsa Posición
Ejemplo del Método de Falsa Posición
Daniela Medina26K vistas
Integracion numerica 1_trapecio por fe0102036
Integracion numerica 1_trapecioIntegracion numerica 1_trapecio
Integracion numerica 1_trapecio
fe01020361.9K vistas
“método de euler y runge kutta” por Astorgo
“método de euler y runge kutta”“método de euler y runge kutta”
“método de euler y runge kutta”
Astorgo1.7K vistas
Algoritmos para matlab por Vitoto96
Algoritmos para matlabAlgoritmos para matlab
Algoritmos para matlab
Vitoto9638.5K vistas
Serie de-taylor-y-maclaurin por FaveeLa Natsuko
Serie de-taylor-y-maclaurinSerie de-taylor-y-maclaurin
Serie de-taylor-y-maclaurin
FaveeLa Natsuko104.4K vistas
Rotacional de un campo vectorial por Emma
Rotacional de un campo vectorialRotacional de un campo vectorial
Rotacional de un campo vectorial
Emma44K vistas
Aplicaciones de las series de fourier en el área de la ingeníeria por elen mora
Aplicaciones de las series de fourier en el área de la ingeníeriaAplicaciones de las series de fourier en el área de la ingeníeria
Aplicaciones de las series de fourier en el área de la ingeníeria
elen mora51.5K vistas
Cálculo Raíces Con Octave por Cristobal Lopez
Cálculo Raíces Con OctaveCálculo Raíces Con Octave
Cálculo Raíces Con Octave
Cristobal Lopez31.6K vistas
Tabla de derivadas por Juan Paez
Tabla de derivadasTabla de derivadas
Tabla de derivadas
Juan Paez78.1K vistas
Diferenciación por 3 y 5 puntos por alan moreno
Diferenciación por 3 y 5 puntosDiferenciación por 3 y 5 puntos
Diferenciación por 3 y 5 puntos
alan moreno26.2K vistas
Ejercicios resueltos de dependencia e independencia lineal por algebra
Ejercicios resueltos de dependencia e independencia linealEjercicios resueltos de dependencia e independencia lineal
Ejercicios resueltos de dependencia e independencia lineal
algebra205.9K vistas
Solucionario ecuaciones diferenciales por Daniel Mg
Solucionario ecuaciones diferencialesSolucionario ecuaciones diferenciales
Solucionario ecuaciones diferenciales
Daniel Mg318.7K vistas
265131074 derivadas-parciales (1) por Manuel Miranda
265131074 derivadas-parciales (1)265131074 derivadas-parciales (1)
265131074 derivadas-parciales (1)
Manuel Miranda33.6K vistas
Solucionario de ejercicios y problemas de ecuaciones diferenciales ordinarias... por Oscar Lopez
Solucionario de ejercicios y problemas de ecuaciones diferenciales ordinarias...Solucionario de ejercicios y problemas de ecuaciones diferenciales ordinarias...
Solucionario de ejercicios y problemas de ecuaciones diferenciales ordinarias...
Oscar Lopez37.2K vistas
Regla de simpson un tercio para segmentos multiples por Tensor
Regla de simpson un tercio para segmentos multiplesRegla de simpson un tercio para segmentos multiples
Regla de simpson un tercio para segmentos multiples
Tensor10.6K vistas
Transformadas de laplace 1 por Utp arequipa
Transformadas de laplace 1Transformadas de laplace 1
Transformadas de laplace 1
Utp arequipa36.2K vistas

Similar a Badillo riosyortizdelaluz

Métodos numéricos aplicados a la mecanica por
Métodos numéricos aplicados a la mecanicaMétodos numéricos aplicados a la mecanica
Métodos numéricos aplicados a la mecanicaEdwin Alexis SemiNArio Beltran
8.1K vistas12 diapositivas
Silabo matem+ütica william juan-net-w7 por
Silabo matem+ütica william juan-net-w7Silabo matem+ütica william juan-net-w7
Silabo matem+ütica william juan-net-w7danielmic78
1.7K vistas14 diapositivas
Guia_programación Comp-EstructurasControl.pdf por
Guia_programación Comp-EstructurasControl.pdfGuia_programación Comp-EstructurasControl.pdf
Guia_programación Comp-EstructurasControl.pdfMixelHernandez
5 vistas21 diapositivas
Curso propedeutico 2016 por
Curso propedeutico 2016Curso propedeutico 2016
Curso propedeutico 2016Rodolfo Alcantara Rosales
1.9K vistas129 diapositivas
Curso propedeutico 2016 por
Curso propedeutico 2016Curso propedeutico 2016
Curso propedeutico 2016rodolfo alcantara rosales
363 vistas129 diapositivas
2 Taller modelacion matemática 2018-1 UNAL por
2 Taller modelacion matemática 2018-1 UNAL2 Taller modelacion matemática 2018-1 UNAL
2 Taller modelacion matemática 2018-1 UNALBERTHING GUTIERREZ BRENIS
590 vistas39 diapositivas

Similar a Badillo riosyortizdelaluz(20)

Silabo matem+ütica william juan-net-w7 por danielmic78
Silabo matem+ütica william juan-net-w7Silabo matem+ütica william juan-net-w7
Silabo matem+ütica william juan-net-w7
danielmic781.7K vistas
Guia_programación Comp-EstructurasControl.pdf por MixelHernandez
Guia_programación Comp-EstructurasControl.pdfGuia_programación Comp-EstructurasControl.pdf
Guia_programación Comp-EstructurasControl.pdf
MixelHernandez5 vistas
Practica N° 2 Informe matrices y determinantes por Alexis Ante
Practica N° 2 Informe matrices y determinantes Practica N° 2 Informe matrices y determinantes
Practica N° 2 Informe matrices y determinantes
Alexis Ante1.1K vistas
Notas analisis algoritmos_vf por Fany Lopez
Notas analisis algoritmos_vfNotas analisis algoritmos_vf
Notas analisis algoritmos_vf
Fany Lopez420 vistas
Python por 199530zx
PythonPython
Python
199530zx689 vistas
Programamatematicas por favalenc
ProgramamatematicasProgramamatematicas
Programamatematicas
favalenc697 vistas
Curso reforzamiento3 por Erendi SB
Curso reforzamiento3Curso reforzamiento3
Curso reforzamiento3
Erendi SB798 vistas
Ts cur-reg-matematicas-iii GHI por nestor riquejo
Ts cur-reg-matematicas-iii GHITs cur-reg-matematicas-iii GHI
Ts cur-reg-matematicas-iii GHI
nestor riquejo48 vistas
Aplicación de análisis numérico en alabes por MateoLeonidez
Aplicación de análisis numérico en alabesAplicación de análisis numérico en alabes
Aplicación de análisis numérico en alabes
MateoLeonidez3K vistas
Deber 7-cap-2-matlab-nise por ALEX PORRAS
Deber 7-cap-2-matlab-niseDeber 7-cap-2-matlab-nise
Deber 7-cap-2-matlab-nise
ALEX PORRAS906 vistas

Último

La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1 por
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1Angel Borroy López
6 vistas22 diapositivas
Tecnologia (1).pdf por
Tecnologia (1).pdfTecnologia (1).pdf
Tecnologia (1).pdfnosi6702
9 vistas13 diapositivas
Tecnologia (3).pdf por
Tecnologia (3).pdfTecnologia (3).pdf
Tecnologia (3).pdfnosi6702
7 vistas15 diapositivas
MasterMind.pdf por
MasterMind.pdfMasterMind.pdf
MasterMind.pdfrtovarfernandez
18 vistas5 diapositivas
Operations & Data Graph por
Operations & Data GraphOperations & Data Graph
Operations & Data GraphNeo4j
42 vistas25 diapositivas
Peña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptx por
Peña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptxPeña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptx
Peña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptxMOISESPENAANAYA
6 vistas8 diapositivas

Último(8)

La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1 por Angel Borroy López
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1
Tecnologia (1).pdf por nosi6702
Tecnologia (1).pdfTecnologia (1).pdf
Tecnologia (1).pdf
nosi67029 vistas
Tecnologia (3).pdf por nosi6702
Tecnologia (3).pdfTecnologia (3).pdf
Tecnologia (3).pdf
nosi67027 vistas
Operations & Data Graph por Neo4j
Operations & Data GraphOperations & Data Graph
Operations & Data Graph
Neo4j42 vistas
Peña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptx por MOISESPENAANAYA
Peña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptxPeña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptx
Peña_Anaya_TAREA Reportes Maestro - Detalle con el uso de AJAX.pptx
MOISESPENAANAYA6 vistas
Aws Community Day Guatemala Criptografia con AWS KMS por Mario IC
Aws Community Day Guatemala Criptografia con AWS KMSAws Community Day Guatemala Criptografia con AWS KMS
Aws Community Day Guatemala Criptografia con AWS KMS
Mario IC26 vistas
Qué es el rodamiento hacia adelante.docx por FabianCarrillo31
Qué es el rodamiento hacia adelante.docxQué es el rodamiento hacia adelante.docx
Qué es el rodamiento hacia adelante.docx
FabianCarrillo317 vistas

Badillo riosyortizdelaluz

  • 1. UNIVERSIDAD VERACRUZANA FACULTAD DE INGENIE RÍA MECÁNICA ELÉCTRICA “ M A N U A L D E P R O G R A M A S AP LICADOS A MÉTODOS N U M É R I C O S ” TRABAJO PRÁCTICO EDUCATIVO PARA ACREDITAR LA EXPERIENCIA EDUCATIVA DE: TRABAJO RECEPCIONAL P R E S E N T A: Juan Ar turo Badi l lo Rios José Lui s Or t iz de la luz DIRECTOR DE TRABAJO PRÁCTICO EDUCATIVO: ISC. KARLOS REYES OR TEGA POZA RICA DE HGO; VER. 2011
  • 2. ÍNDICE INTRODUCCIÓN CAPITULO I 1 JUSTIFICACIÓN 3 TIPO Y NATURALEZA DEL TRABAJO 3 CARACTERÍSTICAS Y FUNCIONES ESCENCIALES CAPITULO II PROCESOS DEL TRABAJO 3 1.- ECUACIONES LINEALES 6 1.1.- Definición y clasificación 6 1.2.- Gauss Simple 6 1.2.1.- Ejemplo propuesto 9 1.2.2.- Diagrama de Flujo 11 1.2.3.- Pseudocódigo 13 1.2.4.- Programas en C 13 1.2.5.- Demostración del Programa 15 1.3.- Gauss Seidel 16 1.3.1.- Ejemplo propuesto 17 1.3.2.- Diagrama de Flujo 19 1.3.3.- Pseudocódigo 20 1.3.4.- Programas en C 21 1.3.5.- Demostración del Programa 23 1.4.- Gauss Jordan 25 1.4.1.- Ejemplo propuesto 25 1.4.2.- Diagrama de Flujo 28 1.4.3.- Pseudocódigo 30 1.4.4.- Programas en C 32
  • 3. 1.4.5.- Demostración del Programa 33 2.- ECUACIONES NO LINEALES 34 2.1.- Definición y tipos de ecuaciones no lineales 34 2.2.- Bisección 35 2.2.1.- Ejemplo propuesto 36 2.2.2.- Diagrama de Flujo 39 2.2.3.- Pseudocódigo 40 2.2.4.- Programas en C 41 2.2.5.- Demostración del Programa 42 2.3.- Falsa Posición 43 2.3.1.- Ejemplo propuesto 45 2.3.2.- Diagrama de Flujo 47 2.3.3.- Pseudocódigo 48 2.3.4.- Programas en C 49 2.3.5.- Demostración del Programa 51 2.4.- Newton-Raphson 52 2.4.1.- Ejemplo propuesto 53 2.4.2.- Diagrama de Flujo 55 2.4.3.- Pseudocódigo 56 2.4.4.- Programas en C 56 2.4.5.- Demostración del Programa 57 3.- ECUACIONES DIFERENCIALES ORDINARIAS 58 3.1.- Concepto y clasificación 58 3.2.- Euler 59 3.2.1.- Ejemplo propuesto 60 3.2.2.- Diagrama de Flujo 64 3.2.3.- Pseudocódigo 65
  • 4. 3.2.4.- Programas en C 66 3.2.5.- Demostración del Programa 67 3.3.-Runge-Kutta 68 3.3.1.- Ejemplo propuesto 69 3.3.2.- Diagrama de Flujo 71 3.3.3.- Pseudocódigo 72 3.3.4.- Programas en C 74 3.3.5.- Demostración del Programa 75 4.- INTEGRACIÓN 76 4.1.- Concepto y clasificación 76 4.2.- Simpson 1/3 76 4.2.1.- Ejemplo propuesto 77 4.2.2.- Diagrama de Flujo 80 4.2.3.- Pseudocódigo 81 4.2.4.- Programas en C 82 4.2.5.- Demostración del Programa 83 COSTOS CAPITULO III 84 APORTACIONES Y CONTRIBUCIONES AL DESARROLLO 86 BIBLIOGRAFÍA 87 ANEXOS 88
  • 5. 1 INTRODUCCIÓN Los métodos numéricos son técnicas mediante las cuales es posible resolver problemas mediante el uso de operaciones aritméticas. Este manual tiene como meta dejar plasmados los métodos más importantes que abarca la experiencia educativa de métodos numéricos para la solución de sistemas de ecuaciones lineales, no lineales y a su vez de derivadas e integrales. Cabe destacar que el objetivo fundamental de este trabajo es ofrecer una guía práctica para que los estudiantes puedan seguir paso a paso la elaboración de los programas desde el desarrollo de los algoritmos a través de los diagramas de flujo hasta la realización del código fuente pasando por las etapas de compilación y ejecución exitosa del programa.
  • 7. 3 JUSTIFICACIÓN Dada la importancia que tienen los métodos numéricos en ingeniería, el alumno necesita entender y comprender la experiencia educativa no solo desde un enfoque teórico sino también práctico, entendido esto como la generación de los programas para aplicar los métodos aprendidos durante la experiencia educativa, brindándoles así una herramienta que podrán utilizar en el ámbito laboral y les permitirá ahorrar tiempo y esfuerzo, debido a que mediante la aplicación de los métodos numéricos es posible manejar sistemas de ecuaciones grandes los cuales de otra forma serian difíciles de resolver de forma analítica. Sin embargo, ésta materia actualmente no cuenta con un manual para el desarrollo de los programas que apliquen los diferentes métodos vistos en clase; por tal motivo, éste trabajo pretende ser una guía al momento de cursar esta experiencia y ahorrar tiempo al alumno en la investigación del programa, desarrollo y aplicación de los mismos. TIPO Y NATURALEZA DEL TRABAJO El tipo de trabajo es práctico educativo donde la información será seleccionada y estructurada con el fin de contribuir en el aprendizaje de los estudiantes y como soporte académico para los docentes que imparten la experiencia educativa de métodos numéricos dentro de la Universidad Veracruzana, así mismo permitirá mejorar las bases para la aplicación de los métodos numéricos mediante programas los cuales sirven como herramienta para la solución de problemas en ingeniería. CARACTERÍSTICAS Y FUNCIONES ESCENCIALES El manual incluirá específicamente los temas de mayor interés para los estudiantes de la Facultad de Ingeniería Mecánica Eléctrica, los cuales servirán como apoyo al cursar la experiencia educativa de métodos numéricos. La función principal de este trabajo, será proporcionar al alumno las bases para conocer y aplicar los fundamentos de los métodos numéricos para la solución de problemas de ingeniería, implementando diversos algoritmos a través de un lenguaje de programación como el Lenguaje C y de esta manera obtener por consecuencia programas que permitan mejorar el entendimiento de los métodos numéricos.
  • 10. 1.- ECUACIONES LINEALES 1.1.- Definición y clasificación En este capítulo estudiaremos las técnicas de solución de sistemas de ecuaciones lineales cuadrados Ax = b. Un sistema de ecuaciones lineales, también conocido como sistema lineal de ecuaciones o simplemente sistema lineal, es un conjunto de ecuaciones lineales sobre un cuerpo o un anillo conmutativo. El problema consiste en encontrar los valores desconocidos de las variables x1, x2 y x3 que satisfacen las tres ecuaciones. Para establecer la velocidad de cálculo y el "trabajo computacional" en los métodos directos, se analiza el número de operaciones de éstos y con base en ello se determinan sus necesidades de memoria. Como consecuencia de lo anterior, se da particular atención a los sistemas especiales: simétricos, bandeados y dispersos, entre otros. Así, estudiaremos los métodos que aprovechan estas características para lograr reducir con esto el número de operaciones y los requerimientos de máquina. Posteriormente se exponen y se desarrollan tres métodos numéricos aplicados a las ecuaciones lineales como son: Gauss Simple, Gauss Seidel y Gauss Jordan. Dado que el mundo real puede verse como un grupo de objetos o partes trabajando en conjunto o bien conectadas de alguna manera formando un todo, brindar al alumno una mejor comprensión de la extraordinaria cantidad de situaciones que pueden representarse con los sistemas o grupos de ecuaciones donde cada una de ellas corresponde a alguna de sus partes, por ejemplo: en circuitos, estructuras. 1.2.- Gauss Simple Esta técnica básica puede extenderse a sistemas grandes de ecuaciones desarrollando un esquema sistemático o algorítmico para eliminar incógnitas y sustituir hacia atrás. La eliminación de Gauss es el más básico de dichos esquemas. Aquí se presentan las técnicas sistemáticas para la eliminación hacia adelante y la sustitución hacia atrás que la eliminación gaussiana comprende. Dado que éstas técnicas son muy adecuadas para utilizarse en computadoras, se requieren algunas modificaciones para obtener un algoritmo confiable. En particular, el programa debe evitar la división entre cero. Al siguiente método se le llama eliminación gaussiana simple, ya que no evita este problema. 6
  • 11. 7 El método está ideado para resolver un sistema general de n ecuaciones: a11x1+a12x2+a13x3+….+a1nxn=b1 (Ec. 1.1a) a21x1+a22x2+a23x3+….+a2nxn=b2 (Ec. 1.1b) . . . . an1x1+an2x2+an3x3+….+annxn=bn (Ec. 1.1c) Como en el caso de dos ecuaciones, la técnica para resolver ecuaciones consiste en dos fases: la eliminación de las incógnitas y su solución mediante sustitución hacia atrás. La eliminación hacia adelante de incógnitas. La primera fase consiste en reducir el conjunto de ecuaciones a un sistema triangular superior (figura 1.1). El paso inicial será eliminar la primera incógnita, x1, desde la segunda hasta la n-ésima ecuación. Para ello se multiplica la ecuación (Ec. 1.1) por para obtener (Ec. 1.2) Ahora, esta ecuación se resta de la ecuación (Ec. 1.2) para dar O Donde el superíndice prima indica que los elementos han cambiado sus valores originales
  • 12. 8 Figura 1.1 Eliminación hacia adelante Las dos fases de la eliminación de Gauss: eliminación hacia adelante y sustitución hacia atrás. Los superíndices prima indican el número de veces que se han modificado los coeficientes y constantes. El procedimiento se repite después con las ecuaciones restantes. Por ejemplo, la ecuación (Ec. 1.1) se puede multiplicar por y el resultado se resta de la tercera ecuación. Se repite el procedimiento con las ecuaciones restantes y da como resultado el siguiente sistema modificado: a11x1+a12x2+a13x3+….+a1nxn=b1 (Ec. 1.3a) a´22x2+a´23x3+….+a´2nxn=b´2 (Ec. 1.3b) a´32x2+a´33x3+….+a´3nxn=b´3 (Ec. 1.3c) a´n2x2+a´n3x3+….+a´nnxn=b´n (Ec. 1.3d) En los pasos anteriores, la ecuación (Ec. 1.1a) se llama la ecuación pivote, y se denomina el coeficiente o elemento pivote. Observe que el proceso de multiplicación del primer renglón por es equivalente a dividirla entre y multiplicarla por . Algunas veces la operación de división es referida a la normalización. Se hace esta distinción porque un elemento pivote cero llega a interferir con la normalización al causar una división entre cero. Más adelante se regresará a este punto importante, una vez que se complete la descripción de la eliminación de Gauss simple. Ahora se repite el procedimiento antes descrito para eliminar la segunda incógnita en las ecuaciones (Ec. 1.3c) hasta (Ec. 1.3d). Para realizar esto, multiplique la ecuación (Ec. 1.3b) por y reste el resultado de la ecuación (Ec. 1.3c). Se realiza la eliminación en forma similar en las ecuaciones restantes para obtener. a11x1+a12x2+a13x3+….+a1nxn=b1 a´22x2+a´23x3+….+a´2nxn=b´2 a´´33x3+….+a´´3nxn=b´´3 . . . . a´´n2x2+a´´n3x3+….+a´nnxn=b´n Sustitución hacia atrás
  • 13. Donde el superíndice biprima indica que los elementos se han modificado dos veces. El procedimiento puede continuar usando las ecuaciones pivote restantes. La última manipulación en esta secuencia es el uso de la ésima ecuación para eliminar el término de la -ésima ecuación. Aquí el sistema se habrá transformado en un sistema triangular superior 9 (Ec. 1.4a) (Ec. 1.4b) (Ec. 1.4c) . . . . . (Ec. 1.4d) 1.2.1.- Ejemplo propuesto Para resolver el siguiente conjunto de ecuaciones. Emplee la eliminación de Gauss (Ec.1.5) (Ec.1.6) (Ec.1.7) Las operaciones se efectuarán usando seis cifras significativas. La primera parte del procedimiento es la eliminación hacia adelante. Se multiplica la ecuación (Ec. 1.5) por (0.1)/3 y se resta el resultado de la ecuación (Ec. 1.6) para obtener Después, se multiplica la ecuación (Ec. 1.5) por (0.3)/3 y se resta de la ecuación (Ec.1.7) para eliminar . Luego de efectuar estas operaciones, el sistema de ecuaciones es (Ec.1.8) (Ec.1.9) (Ec.1.10)
  • 14. Para completar la eliminación hacia adelante, debe eliminarse de la ecuación (Ec.1.10). Para llevar a cabo esto, se multiplica la ecuación (Ec.1.9) por - 0.190000/7.00333 y se resta el resultado de la ecuación (Ec.1.10). Esto elimina 10 de la tercera ecuación y reduce el sistema a una forma triangular superior: (Ec.1.11) (Ec.1.12) (Ec.1.13) Ahora se pueden resolver estas ecuaciones por sustitución hacia atrás. En primer lugar, de la ecuación (Ec.1.13) se despeja x3 (Ec.1.14) Este resultado se sustituye en la ecuación (Ec.1.12): 7.003332 - 0.293333 (7.00003) = -19.5617 de la que se despeja (Ec.1.15) Por último, las ecuaciones (Ec.1.14) y (Ec.1.15) se sustituyen en la (Ec.1.8): 3 - 0.1 (-2.50000) - 0.2 (7.00003) = 7.85 de la que se despeja, aunque hay un pequeño error de redondeo en la ecuación (Ec.1.14), los resultados son muy cercanos a la solución exacta, . Esto se verifica al sustituir los resultados en el sistema de ecuaciones original
  • 15. 11 1.2.2.- Diagrama de flujo Diagrama de Flujo Gauss Simple eliminación hacia adelante
  • 16. 12 Diagrama de Flujo Gauss Simple sustitución hacia atrás
  • 17. 13 1.2.3.- Pseudocódigo a) DO k = 1, n – 1 DO i = k + 1, n factor = DO j = k + 1 to n ai,j = ai,j – factor . ak,j END DO bi = bi - factor • END DO END DO b) xn = bn / an,n DO i=n-1, 1,-1 sum = O DO j = i + 1, n sum = sum + ai,j . xj END DO xi = (bi - sum) / ai, i END DO Pseudocódigo que realiza a) la eliminación hacia adelante y b) la sustitución hacia atrás. 1.2.4.- Programas en C Gauss Simple #include <math.h> #include <stdio.h> /*para printf(),scanf()*/ #include <conio.h> /*para getch(),clrscr()*/ //#include <stdlib.h>/*para exit()*/ //#include <dos.h> #define NUMEL 20 #define INTERVALOS 0 float A[25][25], B[25], S[25],X[25]; MAIN printf("n METODO DE GAUSS SIMPLE"); printf("n Numero de Ecuaciones = "); scanf("%d",&n); printf("n Inserte cada uno de los coeficientesn"); for(i=1;i<=n;i++) { printf("n Fila %d n",i); for(j=1;j<=n;j++) { printf(" Ingrese A(%d,%d) = ",i,j); scanf("%f",&A[i][j]); } } printf("n Inserte cada uno de los terminos independientesn"); for(i=1;i<=n;i++){ { printf(" Ingrese B(%d) = ",i); scanf("%f",&B[i]); } }
  • 18. 14 printf("n Tolerancia para el calculo = "); scanf("%f",&tol); Gauss( n,tol, &er ); printf("nn RAICES DEL SISTEMAn "); for(i=1;i<=n;i++){ printf("n X(%d) = %6.4f",i,X[i]); } printf("nn Fin del programa"); getch(); } void Gauss( int n, float tol, int *er){ int i,j; // IMPRESION DE LOS COEFICIENTES RECIBIDOS /* printf("n IMPRESION DE COEFICIENTESn"); for(i=1;i<=n;i++) { printf("n Fila %d n",i); for(j=1;j<=n;j++) { printf(" A(%d,%d) = %f",i,j, A[i][j]); } printf("n"); } getch(); */ *er = 0; for (i=1;i<=n;i++){ S[i] = abs(A[i][1]); for(j=2;j<=n;j++) if( abs(A[i][j]>S[i])) S[i] = A[i][j]; }
  • 19. 15 1.2.5.- Demostración del programa
  • 20. 1.3.- Gauss Seidel El método de Gauss-Seidel emplea valores iniciales y después itera para obtener las mejores aproximaciones a la solución. El método de Gauss-Seidel es particularmente adecuado cuando se tiene gran número de ecuaciones. Los métodos de eliminación pueden estar sujetos a errores de redondeo. Debido a que el error en el método de Gauss-Seidel es determinado por el número de iteraciones, no es un tema que preocupe. Aunque existen ciertos ejercicios donde la técnica de Gauss-Seidel no convergerá al resultado correcto, estudiaremos otras ventajas que se tienen dicho método. Una matriz bandeada es una matriz cuadrada en donde la diagonal principal son valores diferentes a cero (valor=1) y los que se encuentran fuera de la diagonal son ceros. Los sistemas bandeados se encuentran con frecuencia en la práctica científica y de la ingeniería. Por ejemplo, tales sistemas aparecen en la solución de ecuaciones diferenciales. Aunque la eliminación de Gauss o la convencional se emplean para resolver sistemas de ecuaciones bandeados, resultan ser ineficientes, debido a que si el pivoteo no es necesario, ninguno de los elementos fuera de la banda cambiará su valor original igual a cero. Así, será necesario utilizar tiempo y espacio en el almacenamiento y en el manejo de estos ceros inútiles. Si se sabe de antemano que el pivoteo no es necesario, se pueden desarrollar algoritmos muy eficientes en los que no intervengan los ceros fuera de la banda. Como en muchos problemas con sistemas bandeados, no se requiere el pivoteo; los algoritmos alternos, que se describirán a continuación, son los métodos seleccionados para tal fin. El método de Gauss-Seidel es el método iterativo más comúnmente usado. Suponga que se da un sistema de n ecuaciones: Suponga que se limita a un conjunto de ecuaciones de 3 x 3. Si los elementos de la diagonal no son todos cero, la primera ecuación se puede resolver para la segunda para y la tercera para , para obtener 16 (Ec.1.16a) (Ec.1.16b) (Ec.1.16c) Ahora, se puede empezar el proceso de solución al escoger valores iniciales para las . Una forma simple para obtener los valores iniciales es suponer que todos son cero. Estos ceros se sustituyen en la ecuación (Ec.1.16a), la cual se utiliza para calcular un nuevo valor Después, se sustituye este nuevo valor de junto con el valor previo cero de en la ecuación (Ec.1.16b) y se calcula el nuevo valor de . Este proceso se repite con la ecuación (Ec.1.16c) para calcular un nuevo valor de . Después se regresa a la primera ecuación y se repite todo el procedimiento hasta que la solución converja suficientemente cerca de los valores verdaderos. La convergencia se verifica usando el criterio de la siguiente ecuación de error relativo porcentual.
  • 21. 17 (Ec.1.17) Para toda las donde y son las iteraciones actuales y previas respectivamente. 1.3.1.- Ejemplo propuesto Planteamiento del problema. Use el método de Gauss-Seidel para obtener la solución del sistema usado en el ejemplo: Recuerde que la verdadera solución es . Solución. Primero, despeje la incógnita sobre la diagonal para cada una de las ecuaciones. (Ec.1.18a) (Ec.1.18b) (Ec.1.18c) Suponiendo que son cero, se utiliza la ecuación (Ec.1.18a) para calcular Este valor, junto con el valor de = 0, se sustituye en la ecuación (Ec.1.18b) para calcular
  • 22. 18 la primera iteración termina al sustituir los valores calculados para en la ecuación (Ec.1.18c) para dar en la segunda iteración, se repite el mismo proceso para calcular El método es, por lo tanto, convergente hacia la verdadera solución. Es posible aplicar iteraciones adicionales para mejorar los resultados. Sin embargo, es un problema real no se podría saber con anticipación el resultado correcto. En consecuencia, la ecuación (Ec.1.17) nos da un medio para estimar el error relativo porcentual. Por ejemplo, para , Para los errores estimados son . Observe que, como cuando se determinaron las raíces de una sola ecuación, las formulaciones como la ecuación (Ec.1.17) de Error relativo porcentual, usualmente ofrecen una valoración conservativa de la convergencia. Así, cuando estas se satisfacen aseguran que el resultado se conozca con al menos, la tolerancia especificada por .
  • 23. 19 1.3.2.- Diagrama de flujo Diagrama de Flujo Gauss Seidel
  • 24. 20 1.3.3.- Pseudocódigo SUBROUTINE Gseid (a, b, n, x, imax, es, lambda) DO i = 1,n dummy = ai.i DO j = 1,n ai,j = ai,j / dummy END DO bi = ai / dummy END DO DO i = 1, n sum = bi DO j = 1, n IF i j THEN sum =sum – ai, j *xj END DO xi = sum END DO iter =1 DO centinela = 1 DO i = 1, n old = xi sum = bi DO j = 1, n IF i j THEN sum =sum – ai, j *xj END DO xi = lambda * sum +( 1 - lambda) * old IF centinela = 1 AND x1 0 . THEN ea=ABS (( xi –old) / xi )*100. IF ea es THEN centinela = 0 END IF END DO iter = iter + 1 IF centinela = 1 OR (iter I max) EXIT END DO END Gseid
  • 25. 21 1.3.4. - Programas en C GAUSS SEIDEL #include <stdio.h> #include <math.h> #include <iostream.h> #include <conio.h> #define L 10 #define P L MAIN cout<<"nn METODO DE GAUSS SEIDEL "; cout<<"nn Numero de incognitas Posibles en el sistema: "; scanf("%d",&n); Gauss_Seidel(n); titulo(n); resultados(); cout<<"nnLos resultado son "; for(x=0;x<n;x++) { RESULTADOS[x]=X[x]; cout<<"nX["<<x<<"]= "<<RESULTADOS[x]; } getch(); } void resultados() { int q=0,i=1,t=3,s=n,r=0; int sw=0,w=0,ite=0,h=0; while((sw==0)&&(w<20)) { h=0; while(h<n) { if(tabla[r]==tabla[r+s]) { cont++; } if(cont==n) sw=1; r++; s++; h++; } ite++; w++; } w=ite-1; for(int j=0;j<w;j++) { t=t+2; if((i%10==0)) { textcolor(LIGHTRED+BLINK); gotoxy(5,t-2); cprintf("nn ­­­Presione una tecla para ingresar ala tabla!!! "); getch(); textcolor(GREEN); clrscr(); t=5; titulo(n); } gotoxy(15,t);cout<<i<<"ø"; int y=20,z=0; for(int r=0;r<n;r++)
  • 26. 22 { gotoxy(y+z,t);cout<<tabla[q]; q++; z=z+10; } i++; } } void main() {
  • 27. 23 1.3.5.- Demostración del programa
  • 28. 24
  • 29. 25 1.4.- Gauss Jordan El método de Gauss-Jordan es una variación de la eliminación de Gauss. La principal diferencia consiste en que cuando una incógnita se elimina en el método de Gauss-Jordan. Ésta es eliminada de todas las otras ecuaciones, no sólo de las subsecuentes. Además, todos los renglones se normalizan al dividirlos entre su elemento pivote. De esta forma, el paso de eliminación genera una matriz identidad en vez de una triangular (figura 1.2). En consecuencia, no es necesario usar la sustitución hacia atrás para obtener la solución. El método se ilustra mejor con un ejemplo. Figura 1.2 Representación gráfica del método de Gauss-Jordan. 1.4.1.- Ejemplo propuesto Método de Gauss-Jordan Para resolver el siguiente conjunto de ecuaciones. Con la técnica de Gauss-Jordan Solución. Primero, exprese los coeficientes y el lado derecho como una matriz au-mentada 3 -0.1 -0.2 7.85 0.1 7 -0.3 -19.3 0 -0.2 10 71.4
  • 30. Luego normalice el primer renglón, dividiéndolo entre el elemento pivote, 3, para obtener 26 1 -0.0333333 -0.066667 2.61667 0.1 7 -0.3 -19.3 0.3 -0.2 10 71.4 El término se elimina del segundo renglón restando 0.1 veces al primer renglón del segundo. En forma similar, restando 0.3 veces el primer renglón del tercero, se eliminará el término del tercer renglón: 1 -0.0333333 -0.066667 2.61667 0 7.00333 -0.293333 -19.5617 0 -0.190000 10.0200 70.6150 En seguida, se normaliza el segundo renglón dividiéndolo entre 7.00333: 1 -0.0333333 -0.066667 2.61667 0 1 -0.0418848 - 2.79320 0 -0.190000 10.0200 70.6150 Al reducir los términos x2 de las ecuaciones primera y tercera se obtiene 1 0 -0.0680629 2.52356 0 1 -0.0418848 -2.79320 0 0 10.01200 70.0843 El tercer renglón se normaliza después al dividirlo entre 10.0120: 1 0 -0.0680629 2.52356 0 1 -0.0418848 -2.79320 0 0 1 7.00003
  • 31. Por último los términos se pueden eliminar de la primera y segunda ecuación para obtener 27 1 0 0 3.00000 0 1 0 -2.50001 0 0 1 7.00003 De esta forma, como se muestra en la figura 1.2 la matriz de coeficientes se ha transformado en la matriz identidad, y la solución se obtiene en el vector del lado derecho. Observe que no se requiere la sustitución hacia atrás para llegar a la solución.
  • 32. 28 1.4.2.- Diagrama de Flujo N,M,I,A,J Diagrama de Flujo Gauss Jordan
  • 33. 29 SUBROUTINE GAUSS (N,M,A) I,PIVOTE,A,J,K,N, M,CERO Diagrama de Flujo principal Gauss Jordan subrutina
  • 34. 30 1.4.3.- Pseudocódigo SUB Gauss (a, b, n, x, tol, er) DIMENSION s (n) er = 0 DO i =l, n si = ABS (ai,1 ) DO j = 2, n IF ABS (Ai,j) si THEN si = abs (a i , j) END DO END DO SUB Eliminate (a, s, n, b, tol, er) IF er -1 THEN CALL Substitute (a , n , b, x) END IF END Gauss CALL Eliminate (a, s, n, b, tol, er) DO k = 1, n – 1 CALL Pivot (a, b, s, n, k) IF ABS (ak, k/ sk) tol THEN er = -1 EXIT DO END IF DO i = k +1, n factor = a i, k/ a k, k DO j= k + 1, n ai,j = a i, j - factor*ak,j END DO bi = bi – factor * bk END DO END DO IF ABS (ak,k / sk) tol THEN er = -1 END Eliminate
  • 35. 31 SUB Pivot (a, b, s, n, k) p=k big = ABS(ak,k/sk) DO i i= k + 1, n dummy = ABS(aii,k/sii) IF dummy > big THEN big = dummy p = i i END IF END DO IF p k THEN DO jj = k, n dummy = ap, jj ap, jj = ak, jj ak, jj = dummy END DO dummy = bp bp = bk bk = dummy dummy = sp sp = sk sk = dummy END IF END pivot SUB Substitute (a, n, b, x) xn = bn / an,n DO i = n – 1, 1, -1 sum = 0 DO j = i + 1, n sum = sum + ai,j * xj END DO xi = (bi – sum) / ai,i END DO END Substitute
  • 36. 32 1.4.4.- Programas en C GAUSS JORDAN #include <math.h> #include <stdio.h> /*para printf(),scanf()*/ #include <conio.h> /*para getch(),clrscr()*/ //#include <stdlib.h>/*para exit()*/ //#include <dos.h> #define NUMEL 20 #define INTERVALOS 0 float A[25][25], B[25], S[25],X[25]; MAIN printf("n METODO DE GAUSS JORDAN"); printf("nn Ingrese el numero de incognitas nn Numero de Ecuaciones = "); scanf("%d",&n); printf("n Inserte cada uno de los coeficientesn"); for(i=1;i<=n;i++) { printf("n Fila %d n",i); for(j=1;j<=n+1;j++) { printf(" Ingrese a(%d,%d) = ",i,j); scanf("%f",&a[i][j]); } } m=n+1; do { if(a[1][1]==0) {k=m-1; for(i=2;i<=k;i++) {if(a[i][1]!=0) {for(j=1;j<=m;j++) { apoyo=a[i][j]; a[i][j]=a[1][j]; a[1][j]=apoyo; } } } } else {for(j=2;j<=m;j++) {for(i=2;i<=n;i++) {b[i-1][j-1]=a[i][j]-a[1][j]*a[i][1]/a[1][1];} } for(j=2;j<=m;j++) {b[n][j-1]=a[1][j]/a[1][1];} m=m-1; for(j=1;j<=m;j++) {for(i=1;i<=n;i++) {a[i][j]=b[i][j];} } } } while(m>1); printf("nn RAICES DEL SISTEMAn "); for(i=1;i<=n;i++) {printf("n X(%d) = %1.4f",i,a[i][1]);} printf("nn Fin del programa"); getch(); } }
  • 37. 33 1.4.5.- Demostración del programa
  • 38. 2.- ECUACIONES NO LINEALES 2.1.- Definición y tipos de ecuaciones no lineales En este capítulo estudiaremos diversos métodos para resolver ecuaciones no lineales en una incógnita , aprovechando los conceptos básicos del cálculo y las posibilidades gráficas y de cómputo de la tecnología moderna. Sistemáticamente a la interpretación gráfica de los métodos, a fin de mostrar visualmente su funcionamiento y de enriquecer las imágenes asociadas con ellos; de igual manera, se generan tablas en la aplicación de cada técnica para analizar el comportamiento numérico y eventualmente detener el proceso. Se ha organizado el material como métodos de uno y dos puntos, de los segundos el de posición falsa. Esto, junto con el concepto de orden de convergencia, nos permitirá tener los elementos suficientes para seleccionar la técnica más adecuada para una situación dada. Finalizamos el capítulo con las técnicas para resolver ecuaciones polinomiales. El propósito de este capítulo es que el estudiante cuente con los elementos básicos, computacionales y de criterio, apropiados para resolver el problema algebraico clásico de encontrar las raíces reales y complejas de la ecuación , en donde las técnicas algebraicas de "despejar" la incógnita no sean aplicables, como es el caso de , o bien resulten imprácticas. Por último, es importante señalar lo difícil que resulta pensar en un tópico de matemáticas o ingeniería que no involucre ecuaciones de esta naturaleza. La solución de este sistema consta de un conjunto de valores que simultáneamente hacen que todas las ecuaciones sean iguales a cero. Presentamos los métodos, para el caso en que las ecuaciones simultáneas son lineales, es decir, que se puedan expresar en la forma general donde la b y la a son constantes. A las ecuaciones algebraicas y trascendentales que no se pueden expresar de esta forma se les llama ecuaciones no lineales. Por ejemplo, 34 Y son dos ecuaciones simultáneas no lineales con dos incógnitas, y , las cuales se expresan en la forma de la ecuación como Así, la solución serían los valores de y de y que hacen a las funciones y iguales a cero. La mayoría de los métodos para determinar tales soluciones son extensiones de los métodos abiertos para resolver ecuaciones simples.
  • 39. 2.2.- Bisección Al aplicar las técnicas gráficas se observa que cambia de signo a ambos lados de la raíz. En general, si es real y continúa en el intervalo que va desde hasta 35 y y tienen signos opuestos, es decir, (Ec.2.1) entonces hay al menos una raíz real entre y . Los métodos de búsqueda incremental aprovechan esta característica localizando un intervalo en el que la función cambie de signo. Entonces, la localización del cambio de signo (y, en consecuencia, de la raíz) se logra con más exactitud al dividir el intervalo en varios subintervalos. Se investiga cada uno de estos subintervalos para encontrar el cambio de signo. El proceso se repite y la aproximación a la raíz mejora cada vez más en la medida que los subintervalos se dividen en intervalos cada vez más pequeños. Figura 2.1
  • 40. El método de bisección, conocido también como de corte binario, de partición de intervalos o de Bolzano, es un tipo de búsqueda incremental en el que el intervalo se divide siempre a la mitad. Si la función cambia de signo sobre un intervalo, se evalúa el valor de la función en el punto medio. La posición de la raíz se determina situándola sobre el punto medio del subintervalo, dentro del cual ocurre un cambio de signo. El proceso se repite hasta obtener una mejor aproximación. En la figura 2.1 se presenta un algoritmo sencillo para los cálculos de la bisección. En la figura 2.3 se muestra una representación gráfica del método. Los siguientes ejemplos se harán a través de cálculos reales involucrados en el método. 36 2.2.1.- Ejemplo propuesto Planteamiento del problema. Emplee el método de bisección para resolver el siguiente problema. Figura 2.2 El método gráfico para determinar las raíces de una ecuación Solución. El primer paso del método de bisección consiste en asignar dos valores iniciales a la incógnita (en este problema, c) que den valores de con diferentes signos. En la figura 2.2 se observa que la función cambia de signo entre los valores 12 y 16. Por lo tanto, la estimación inicial de la raíz se encontrará en el punto medio del intervalo Dicha aproximación representa un error relativo porcentual verdadero de (note que el valor verdadero de la raíz es 14.7802). A continuación calculamos el producto de los valores en la función en un límite inferior y en el punto medio:
  • 41. que es mayor a cero y, por lo tanto, no ocurre cambio de signo entre el límite inferior y el punto medio. En consecuencia, la raíz debe estar localizada entre 14 y 16. Entonces, se crea un nuevo intervalo redefiniendo el límite inferior como 14 y determinando una nueva aproximación corregida de la raíz 37 Figura 2.3 Una representación gráfica del método de bisección. La gráfica presenta las primeras tres iteraciones del ejemplo 2.2.1 la cual representa un error porcentual verdadero , = 1.5%. Este proceso se repite para obtener una mejor aproximación. Por ejemplo,
  • 42. Por lo tanto, la raíz está entre 14 y 15. El límite superior se redefine como 15 y la raíz estimada para la tercera iteración se calcula así: que representa un error relativo porcentual , = 1 .9%. Este método se repite hasta que el resultado sea suficientemente exacto para satisfacer sus necesidades. En el ejemplo anterior, se observa que el error verdadero no disminuye con cada iteración. Sin embargo, el intervalo donde se localiza la raíz se divide a la mitad en cada paso del proceso. Como se estudiará en la siguiente sección, el ancho del intervalo proporciona una estimación exacta del límite superior del error en el método de bisección. 38
  • 43. 39 2.2.2.- Diagrama de Flujo Diagrama de Flujo Bisección
  • 44. 40 2.2.3.- Pseudocódigo FUNCTION Bisect(xl, xu, es, imax, xr, iter, ea) iter = 0 fl = f(xl) DO xrold = xr xr = (xl + xu) / 2 fr = f( xr ) iter = iter + 1 IF xr 0 THEN ea = ABS((xr – xrold) / xr) * 100 END IF test = fl * fr IF test 0 THEN xu = xr ELSE IF test 0 THEN xl = xr fl= fr ELSE ea = 0 END IF IF ea es OR iter imax EXIT END DO Bisect = xr END Bisect
  • 45. 41 2.2.4.- Programas en C BISECCIÓN #include <math.h> #include <stdio.h> /*para printf(),scanf()*/ #include <conio.h> /*para getch(),clrscr()*/ //#include <stdlib.h>/*para exit()*/ //#include <dos.h> #define NUMEL 20 #define INTERVALOS 0 float A[25][25], B[25], S[25],X[25]; MAIN printf("n METODO DE BISECCIONn"); printf( " Teclea valor minimo = "); scanf("%f",&xmin); printf("n"); printf( " Teclea valor maximo = "); scanf("%f",&xmax); printf("n"); printf( " Teclea valor de error esperado = "); scanf("%f",&error); printf("n"); printf( " Teclea iteraciones maximas = "); scanf("%f",&iteraciones); printf("n"); c1 = Bisect(xmin, xmax, error, iteraciones); printf( " Resultado = %f", c1); getch(); } } float Bisect( float x1,float xu, float es, int imax){ int iter; float f1, fr, test; float xold, xr, ea=0; iter = 0; f1 = F(x1, 10, 40, 68.1); do{ xold = xr; xr = (x1+xu)/2; iter = iter +1; if( xr != 0 ){ ea = abs((xr-xold)/xr)*100; } fr = F(xr, 10, 40, 68.1); test = f1*fr; if( test < 0 ){ // Se determina si hay una raiz entre x1 y xr, cambio de signo xu = xr; } else if ( test > 0 ) { x1 = xr; f1 = fr; } else // Se encontro una raiz ea = 0; // imprimimos los resultados printf( " No X1 Xu Xr ea etn"); printf( " %d %6.3f %6.3f %6.3f %6.3f %6.3f n", iter, x1, xu, xr, ea ) ; }while( (ea >= es) || (iter<imax)); return xr; }
  • 46. 42 2.2.5.- Demostración del programa
  • 47. 43 2.3.- Falsa Posición Aun cuando la bisección es una técnica perfectamente válida para determinar raíces, su método de aproximación por "fuerza bruta" es relativamente ineficiente. La falsa posición es una alternativa basada en una visualización gráfica. Un inconveniente del método de bisección es que al dividir el intervalo de , a en mitades iguales, no se toman en consideración las magnitudes de y de . Por ejemplo, si de está mucho más cercana a cero que de , es lógico que la raíz se encuentre más cerca de que de (figura 2.4). Un método alternativo que aprovecha esta visualización gráfica consiste en unir y con una línea recta. La intersección de esta línea con el eje de las x representa una mejor aproximación de la raíz. El hecho de que se reemplace la curva por una línea recta da una "falsa posición" de la raíz; de aquí el nombre de método de la falsa posición, o en latín, regula falsi. También se le conoce como método de interpolación lineal. Usando triángulos semejantes (fig.2.4) la intersección de la línea recta con el eje de las se estima mediante (Ec. 2.2) en el cual se despeja (Ec. 2.3) Ésta es la fórmula de la falsa posición. El valor de calculado con la ecuación (Ec. 2.3), reemplazará, después, a cualquiera de los dos valores iniciales, o , y da un valor de la función con el mismo signo de . De esta manera, los valores o siempre encierran la verdadera raíz. El proceso se repite hasta que la aproximación a la raíz sea adecuada. El algoritmo es idéntico al de la bisección (figura 2.1), excepto en que la ecuación (Ec. 2.3).
  • 48. 44 Figura 2.4 Representación gráfica del método de la falsa posición con los triángulos semejantes sombreados se obtiene la fórmula para el método. Desarrollo del método de la falsa posición Multiplicando en cruz la ecuación (2.2) obtenemos Agrupando términos y reordenando: Dividiendo entre (Ec. 2.3a) Ésta es una de las formas del método de la falsa posición. Observe que permite el cálculo de la raíz como una función de los valores iniciales inferior y superior . Ésta puede ponerse en una forma alternativa al separar los términos: Sumando y restando en el lado derecho:
  • 49. 45 Agrupando términos se obtiene O La cual es la misma ecuación (Ec. 2.3). Se utiliza esta forma porque implica una evaluación de la función y una multiplicación menos que la ecuación (Ec. 2.3a). 2.3.1.- Ejemplo propuesto Con el método de la falsa posición determine la raíz de la misma ecuación analizada en el ejemplo 2.3 [ecuación (Ec. 2.3a)]. Solución. Se empieza el cálculo con los valores iniciales =12 y = 16. Primera iteración: = 12 = 6.0699 =16 = -2.2688 que tiene un error relativo verdadero de 0.89 por ciento. Segunda iteración: o = -1.5426 Por lo tanto, la raíz se encuentra en el primer subintervalo y xr se vuelve ahora el límite superior para la siguiente iteración, = 14.9113: = 12 = 14.9113 f
  • 50. el cual tiene errores relativos y verdadero y aproximado de 0.09 y 0.79 por ciento. Es posible realizar iteraciones adicionales para hacer una mejor aproximación de las raíces. Se obtiene una idea más completa de la eficiencia de los métodos de bisección y de falsa posición al observar la figura 3.5 donde se muestra el error relativo porcentual verdadero de los ejemplos 3.3 y 3.3.1. Observe cómo el error decrece mucho más rápidamente en el método de la falsa posición que en el de la bisección, debido a un esquema más eficiente en el método de la falsa posición para la localización de raíces. Recuerde que en el método de bisección el intervalo entre y se va haciendo más pequeño durante los cálculos. Por lo tanto, el intervalo, como se define para la primera iteración, proporciona una medida del error en este método. Éste no es el caso con el método de la falsa posición, ya que uno de los valores iniciales puede permanecer fijo durante los cálculos, mientras que el otro converge hacia la raíz. Como en el caso del ejemplo, el extremo inferior permanece en 12, mientras que converge a la raíz. En tales casos, el intervalo no se acorta, sino que se aproxima a un valor constante. 46 Figura 2.5 Comparación de los errores relativos de los métodos de bisección y de falsa posición
  • 51. 47 2.3.2.- Diagrama de Flujo Diagrama de Flujo Falsa Posición
  • 52. 48 2.3.3.- Pseudocódigo FUNCTION ModFalsepos (xl, xu, es, imax, xr, iter, ea) iter = 0 fl = f(xl) fu = f (xu) DO xrold = xr xr = xu – fu * (xl – xu) / (fl – fu) fr = f(xr) iter= iter+1 IF xr 0 THEN ea = Abs((xr – xrold) / xr) * 100 END IF test = fl * fr IF test 0 THEN xu = xr fu = f(xu) iu= 0 il = il + 1 IF il 2 THEN fl = fl / 2 ELSE IF test O THEN xl=xr fl = f (xl) il=0 iu = iu + 1 IF iu 2 THEN fu =fu / 2 ELSE ea = 0 END IF IF ea es OR iter imax THEN EXIT END DO modFalsepos = xr END Modfalsepos
  • 53. 49 2.3.4.- Programas en C #include <math.h> #include <stdio.h> /*para printf(),scanf()*/ #include <conio.h> /*para getch(),clrscr()*/ //#include <stdlib.h>/*para exit()*/ //#include <dos.h> #define NUMEL 20 #define INTERVALOS 0 float A[25][25], B[25], S[25],X[25]; MAIN printf("n METODO DE FALSA POSICIONn"); printf( " Teclea valor minimo = "); scanf("%f",&xmin); printf("n"); printf( " Teclea valor maximo = "); scanf("%f",&xmax); printf("n"); printf( " Teclea valor de error esperado = "); scanf("%f",&error); printf("n"); printf( " Teclea iteraciones maximas = "); scanf("%f",&iteraciones); printf("n"); c1 = Bisect(xmin, xmax, error, iteraciones); c1 = FalsePos( xmin, xmax, error, iteraciones); printf( " Resultado = %f", c1); getch(); } }
  • 54. 50 float FalsePos( float x1,float xu, float es, int imax){ int iter=0, i1, iu; float f1, fr, fu, test; float xrold, xr, ea=0; f1 = F(x1, 10, 40, 68.1); fu = F(xu, 10, 40, 68.1); do{ xrold = xr; xr = xu-fu*(x1-xu)/(f1-fu); fr = F(xr,10,40,68.1); iter = iter +1; if ( xr != 0 ) { ea = abs( (xr - xrold)/xr )* 100; } test = f1 * fr; if( test < 0 ) { xu = xr; fu = F(xu, 10, 40, 68.1); iu = 0; i1 = i1 + 1; if ( i1 >= 2 )f1 = f1 / 2; } else if ( test > 0 ){ x1 = xr; f1 = F(x1, 10, 40, 68.1); i1 = 0; iu = iu +1; if( iu >= 2) fu = fu / 2; } else ea=0; }while( (ea >= es) || (iter<imax)); return xr; }
  • 55. 51 2.3.5.- Demostración del programa
  • 56. 2.4.- Newton-Raphson Tal vez, de las fórmulas para localizar raíces, la fórmula de Newton-Raphson (figura 2.6) sea la más ampliamente utilizada. Si el valor inicial para la raíz es , entonces se puede trazar una tangente desde el punto [ , ] de la curva. Por lo común, el punto donde esta tangente cruza al eje x representa una aproximación mejorada de la raíz. El método de Newton-Raphson se deduce a partir de esta interpretación geométrica. De la figura 2.4, se tiene que la primera derivada en es equivalente a la pendiente: 52 Figura 2.6 Representación gráfica del método de Newton Raphson. Se extrapola una tangente a la función en [esto es, ] hasta el eje x para obtener una estimación de la raíz en . f´ f (Ec.2.4) que se reordena para obtener f f´ (Ec.2.5) La cual se conoce como fórmula de Newton-Raphson.
  • 57. 2.4.1.- Ejemplo propuesto Planteamiento del problema. Utilice el método de Newton-Raphson para calcular la raíz de empleando como valor inicial y se considere como raíz real la iteración en donde exista una similitud de al menos 6 cifras significativas con la iteración anterior. Solución. La primera derivada de la función es 53 que se sustituye, junto con la función original en la ecuación (2.5), para tener
  • 58. 54 Empezando con un valor inicial , se obtuvieron los siguientes resultados: 0 0 100 ' 1 0.500000000 11.8 2 0.566311003 0.147 3 0.567143165 0.0000220 4 0.567143290 < Así, el método converge rápidamente a la raíz verdadera. Observe que el error relativo porcentual verdadero en cada iteración disminuye mucho más rápido que con la iteración simple de punto fijo.
  • 59. 55 2.4.2.- Diagrama de Flujo No convergen en NMI iteraciones Diagrama de Flujo Newton Raphson INICIO NGRAD,N,M,I,A,A PROX,NRAIZ,X,N MI,B,C,Y,REL
  • 60. 56 2.4.3.- Pseudocódigo function newtonIterationFunction(x) { return x - (cos(x) - x^3) / (-sin(x) - 3*x^2) } var x := 0,5 for i from 0 to 99 { print "Iteraciones: " i print "Valor aproximado: " x xold := x x := newtonIterationFunction(x) if x = xold { print "Solución encontrada!" break } } 2.4.4.- Programas en C NEWTON RAPHSON #include <conio.h> #include <stdio.h> #include <math.h> MAIN printf("ttMETODO DE NEWTON RAPHSON"); printf("nnintruce valor inicial"); printf("nnX="); scanf("%f",&x1); printf("nIteraciones="); scanf("%d",&I); do { y=exp(-x1)-x1; y2=-1*exp(-x1)-1; xr=x1 - (y/y2); a=((xr-x1)/xr)*100; e=fabs(a); x1=xr; i++; c++; } while(i<I); printf("nnnnLa raiz aproximada es x%d = %.12f ",c,xr); printf("nnError = %.3f",e); getch(); }
  • 61. 57 2.4.3.- Demostración del programa
  • 62. 3.- ECUACIONES DIFERENCIALES ORDINARIAS 3.1.- Concepto y clasificación En este capítulo se estudiarán, las técnicas numéricas de solución de ecuaciones diferenciales con condiciones iniciales o de frontera, denominados problemas de valor inicial o de frontera, respectivamente. Una ecuación diferencial ordinaria (comúnmente abreviada "EDO") es una relación que contiene funciones de una sola variable independiente, y una o más de sus derivadas con respecto a esa variable. Para esto, se inicia formulando tales problemas, y luego, a partir de las ideas de extrapolación, se plantean métodos como el de Euler. Más adelante, en un proceso de ponderación de pendientes, se obtienen métodos con diferentes órdenes de exactitud donde no se requiere de derivaciones complicadas de funciones, pagándose como precio de ello un mayor número de cálculos. Tales métodos son conocidos como métodos de Runge-Kutta. Basándose en el proceso de integración implicado en la solución de las ecuaciones diferenciales y en la aproximación de funciones se plantean familias de métodos denominados de predicción-corrección. Dado que las ecuaciones diferenciales ordinarias permiten modelar procesos diná-micos tales como: vaciado de recipientes, reactores químicos, movimientos amortiguados, desarrollos poblacionales e incluso situaciones estáticas como la deflexión de vigas y problemas geométricos. Estas técnicas analíticas son necesarias para ciertas ecuaciones muy particulares. Muchas de las leyes generales de la naturaleza se expresan en el lenguaje de las ecuaciones diferenciales; abundan también las aplicaciones en ingeniería, economía, en las mismas matemáticas y en muchos otros campos de la ciencia aplicada. Esta gran utilidad de las ecuaciones diferenciales es fácil de explicar; recuérdese que si se tiene la función su derivada puede interpretarse como la velocidad de cambio de y con respecto a . En cualquier proceso natural, las variables incluidas y sus velocidades de cambio se relacionan entre sí mediante los principios científicos que gobiernan el proceso. El resultado de expresar en símbolos matemáticos estas relaciones, a menudo es una ecuación diferencial. 58
  • 63. 59 3.2.- Euler Este tema se refiere a la solución de ecuaciones diferenciales ordinarias de la forma Recuerde que el método fue de la forma general Nuevo valor = valor anterior + pendiente x tamaño de paso o, en términos matemáticos, (Ec.3.2) De acuerdo con esta ecuación, la pendiente estimada se usa para extrapolar desde un valor anterior a un nuevo valor en una distancia (figura 3.1). Esta fórmula se aplica paso a paso para calcular un valor posterior y, por lo tanto, para trazar la trayectoria de la solución. En otras palabras, se toma la pendiente al inicio del intervalo como una aproximación de la pendiente promedio sobre todo el intervalo. Figura 3.1 Ilustración gráfica del método de un paso.
  • 64. 60 La primera derivada ofrece una estimación directa de la pendiente en (figura 3.2): donde es la ecuación diferencial evaluada en y . La estimación se sustituye la ecuación (Ec.3.1): f (Ec.3.2) Esta fórmula se conoce como método de Euler (o de Euler-Cauchy o de punto pendiente). Se predice un nuevo valor de y, usando la pendiente (igual a la primera deriva en el valor original de x) para extrapolar linealmente sobre el tamaño de paso h (figura 3.2). Figura 3.2 Método de Euler. 3.2.1.- Ejemplo propuesto Planteamiento del problema. Con el método de Euler integre numéricamente la ecuación desde hasta con un tamaño de paso 0.5. La condición inicial en es . Recuerde que la solución exacta está dada por la siguiente ecuación:
  • 65. 61 Solución. Se utiliza la ecuación (Ec.3.2) para implementar el método de Euler: donde y la pendiente estimada en es Por lo tanto, La solución verdadera en es Así, el error es Et = valor verdadero - valor aproximado o , expresada como error relativo porcentual, t = -63.1%. En el segundo paso, La solución verdadera en x = 1.0 es 3.0 y, entonces, el error relativo porcentual es - 95.8%. El cálculo se repite y los resultados se dan en la tabla 3.2.1 y en la figura 3.3. Comparación de los valores verdadero y aproximado de la integral de y'= -2X3+ 1 2.x2 - 20x + 8.5, con la condición inicial de que y = 1 en x = 0. Los valores aproximados se calcularon empleando el método de Euler con un tamaño de paso de 0.5. El error local se refiere al error en que se incurre sobre un solo paso. Éste se calcula con una expansión de la serie de Taylor como en el ejemplo 3.3. El error global es la discrepancia total debida a los pasos anteriores y presentes.
  • 66. 62 Tabla 3.2.1 Error relativo porcentual X Y verdadero Y euler Global Local 0.0 1 .00000 1 .00000 0.5 3.21875 5.25000 -63.1 -63.1 1.0 3.00000 5.87500 -95.8 -28.0 1.5 2.21875 5.12500 131.0 -1.41 2.0 2.00000 4.50000 -125.0 20.5 2.5 2.71875 4.75000 -74.7 17.3 3.0 4.00000 5.87500 46.9 4.0 3.5 4.71875 7.12500 -51.0 -11.3 4.0 3.00000 7.00000 -133.3 -53.0 Figura 3.3 Comparación de la solución verdadera con una solución numérica usando el método de Euler, para la integral de y' = -2X3 + 1 2X2 - 20x + 8.5 desde x = O hasta x = 4 con un tamaño de paso de 0.5. La condición inicial en x = O es y = 1.
  • 67. Observe que aunque el cálculo capta la tendencia general de la solución verdadera, el error resulta considerable. Como se explica en la siguiente sección, es posible reducir tal error usando un tamaño de paso menor. El ejemplo anterior usa un polinomio simple como ecuación diferencial con el objetivo de facilitar el siguiente análisis de error. De esta forma, En efecto, un caso más general (y más común) implica EDO, donde aparece una función que depende tanto de como de , Conforme avancemos en esta parte del texto, nuestros ejemplos comprenderán EDO que dependen de variables independientes y dependientes. 63
  • 68. 64 3.2.2.- Diagrama de flujo Diagrama de Flujo Euler
  • 69. 65 3.2.3.- Pseudocódigo ‘ nt rva o nt grac ón xi = 0 xf = 4 ‘var ab s n c a s x = xi y = 1 ‘ stab c tamaño paso t rm na ‘ núm ro pasos cá c o dx = 0.5 nc= (xf – xi) /dx ‘con c on s sa a PRINT x,y ´ciclo para implementar el método de Euler ‘ sp g r s ta os DO i = 1, nc dydx = -2x3 +12x2 – 20x + 8.5 y = y + dydx . dx x= x + dx PRINT x, y END DO
  • 70. 66 3.2.4.- Programas en C EULER #include <iostream.h> #include <iomanip.h> #include <conio.h> #include <math.h> #include <stdlib.h> #include <dos.h> MAIN return (-2*pow(x,3))+(12*pow(x,2))-(20*x)+8.5; case EULER: Lee(x0,xf,y0,h); Euler(x0,xf,y0,h); getch(); break; case SALIR: gotoxy(34,20); cout<<"Fin de "<<__FILE__; gotoxy(34,21); cout<<"Espere un momento..."; sleep(1); exit(0); break; default: gotoxy(34,15); cout<<"Opcion no permitida"; getch(); break; } }while(op!=SALIR); return 0; } cout<<" METODO DE EULER "; gotoxy(10,4); cout<<"Xo = "<<setw(10)<<setprecision(5)<<x0; gotoxy(10,5); cout<<"Xf = "<<setw(10)<<setprecision(5)<<xf; gotoxy(10,6); cout<<"Yo = "<<setw(10)<<setprecision(5)<<y0; gotoxy(10,7); cout<<"h = "<<setw(10)<<setprecision(5)<<h; gotoxy(10,9); cout<<" x y"; gotoxy(9,10); cout<<"----------------------"; cout<<endl; cout<<setw(10) <<setprecision(5) << setiosflags(ios::fixed) << x; cout<<setw(20) <<setprecision(5) << setiosflags(ios::fixed) << y << endl; while(x<xf){ y+=h*f(x,y); x+=h; cout<<setw(10) <<setprecision(5) << setiosflags(ios::fixed) << x <<setw(20) <<setprecision(5) << setiosflags(ios::fixed) << y << endl; } } void Heun(float x0,float xf,float y0,float h) {
  • 71. 67 3.2.5. - Demostración del programa
  • 72. 3.3.-Runge-Kutta El método de Runge-Kutta (RK) logra la exactitud del procedimiento de la serie Taylor sin necesitar el cálculo de derivadas de orden superior. Existen muchas variantes, pero todas tienen la forma generalizada de la siguiente ecuación. 68 (Ec.3.3) donde se conoce como la función incremento, la cual puede interpretarse como una pendiente representativa en el intervalo. La función incremento se escribe en forma general como (Ec.3.4) donde las son constantes y las son (Ec.3.4a) (Ec.3.4b) (Ec.3.4c) . . . (Ec.3.4d) donde las y son constantes. Observe que las son relaciones de recurrencia. Es decir, aparecen en la ecuación , la cual aparece en la ecuación , etcétera. Como cada es una evaluación funcional, esta recurrencia vuelve eficiente al método de RK para cálculos en computadora. Es posible tener varios tipos de métodos de Runge-Kutta empleando diferentes nú-meros de términos en la función incremento especificada por n. Observe que el método de Runge-Kutta (RK) de primer orden con n=1 es, de hecho, el método de Euler. Una vez que se elige n, se evalúan las a, p y q igualando la ecuación (Ec.3.3) a los términos en la expansión de la serie de Taylor. Así, al menos para las versiones de orden inferior, el número de términos, n, por lo común representa el orden de la aproximación. Por ejemplo, en la siguiente sección, los métodos RK de segundo orden usan la función incremento con dos términos (n – 2).
  • 73. 69 MÉTODO DE RUNGE KUTTA DE SEGUNDO ORDEN La segunda versión de segundo orden de la ecuación (Ec.3.3) es (Ec.3.5) donde (Ec.3.5a) (Ec.3.5b) Como se describe a continuación, los valores de se evalúan al igualar la ecuación (Ec.3.5) con la expansión de la serie de Taylor hasta el término de segundo. 3.3.1.- Ejemplo propuesto Comparación de varios esquemas RK de segundo orden Planteamiento del problema. Utilice el método de Runge Kutta para integrar numéricamente la siguiente ecuación: Con la condición inicial de que y = 1 en x = 0. Los valores aproximados se calcularon con el método RK de segundo orden, con un tamaño de paso de 0.5. RUNGE KUTTA DE SEGUNDO ORDEN 0.0 1 .0000 0 1.00000 0 0.5 3.21875 3.277344 1.8 1.0 3.00000 3.101563 3.4.. 1.5 2.21875 2.347656 5.8 2.0 2.00000 2.140625 7.0 2.5 2.71875 2.855469 5.0 3.0 4.00000 4.117188 2.9 3.5 . 4.71875 4.800781 1.7 4.0 3.00000 3.031250 1.0
  • 74. 70 En el primer intervalo también es igual a 8.5 y La pendiente promedio se calcula mediante que se utiliza para predecir Resolver la siguiente función con la condición inicial en . Los valores aproximados se calcularon utilizando el método de runge kutta con un tamaño de paso igual a 1. 0 2.0000000 2.0000000 0.00 2.0000000 0.00 1 6.1946314 6.7010819 8.18 6.3608655 2.68 2 14.8439219 16.3197819 9.94 15.3022367 3.09 3 33.6771718 37.1992489 10.46 34.7432761 3.17 4 75.3389626 83.3377674 10.62 77.7350962 3.18
  • 75. 71 3.3.2.-Diagrama de flujo Diagrama de Flujo Runge Kutta
  • 76. 72 3.3.3.- Pseudocódigo a) Programa pr nc pa o “man ja or” Asigna valores para n= número de ecuaciones yi= valores iniciales de n variables dependientes xi= valor inicial de la variable independiente xf= valor final de la variable independiente dx= cálculo del tamaño de paso xout= intervalo de salida x = xi m= 0 xpm = x DO I = 1, n ypi,m = yi END DO DO xend = x + xout IF (xend xf) THEN xend = xf h= dx CALL Integrador (x, y, n, h, xend) m = m + 1 xpm = x DO i = 1, n ypi,m = yi END DO IF (x xf) EXIT LOOP DISPLAY RESULTS END
  • 77. 73 b) Rutina para tomar un paso de salida SUB integrator (x, y, n, h, xend) DO IF (xend – x < h) THEN h = xend – x CALL RK4 (x, y, n, h) IF (x xend) EXIT END DO END SUB c) Método RK de cuarto orden para un sistema de EDO SUB RK4(x, y, n, h) CALL Derivs (x, y, k1) DO i = 1, n ymi = yi + k1i * h / 2 END DO CALL Derivs (x + h / 2, ym, k2) DO i = 1, n ymi = yi + k2i * h / 2 END DO CALL Derivs (x + h / 2, ym, k3) DO i = 1, n yei = yi + k3i * h END DO CALL Derivs (x + h, ye, k4) DO i = 1, n slopei = (k1i + 2* (k2i+k3i)+k4i)/6 yi = yi + slopei * h END DO x = x + h END SUB d) Rutina para determinar derivadas SUB Derivs (x, y, dy) dy1 = … dy2 = …. END SUB
  • 78. 74 3.3.4.- Programas en C RUNGE KUTTA #include <iostream.h> #include <iomanip.h> #include <conio.h> #include <math.h> #include <stdlib.h> #include <dos.h> MAIN return 4*exp(0.8*x)-(0.5*y); case RK2: Lee(x0,xf,y0,h); Heun(x0,xf,y0,h); getch(); break; case SALIR: gotoxy(34,20); cout<<"Fin de "<<__FILE__; gotoxy(34,21); cout<<"Espere un momento..."; sleep(1); exit(0); break; default: gotoxy(34,15); cout<<"Opcion no permitida"; getch(); break; } }while(op!=SALIR); return 0; } cout<<"METODO DE HEUN (RK Orden 2)"<<endl; gotoxy(10,4); cout<<"Xo = "<< setw(10) << setprecision(5) <<x0; gotoxy(10,5); cout<<"Xf = "<< setw(10) << setprecision(5) <<xf; gotoxy(10,6); cout<<"Yo = "<< setw(10) << setprecision(5) <<y0; gotoxy(10,7); cout<<"h = "<< setw(10) << setprecision(5) <<h; gotoxy(10,9); cout<<"x y"; gotoxy(9,10); cout<<"----------------------"; cout<<endl; cout<<setw(10) << setprecision(5) << setiosflags(ios::fixed) << x; cout<<setw(20) << setprecision(5) << setiosflags(ios::fixed) << y <<endl; while(x<xf){ k1=h*f(x,y); k2=h*f(x+h,y+k1); y+=(k1/2.0+k2/2.0); x+=h; cout<<setw(10) << setprecision(5) << setiosflags(ios::fixed) << x <<setw(20) << setprecision(5) << setiosflags(ios::fixed) << y <<endl; } } void rk4(float x0,float xf,float y0,float h) {
  • 79. 75 3.3.5.- Demostración del programa
  • 80. 4.- INTEGRACIÓN 4.1.- Concepto y clasificación En este capítulo se abordará el tema clásico de integración definida. Para ello se utilizarán procesos finitos, en los que a diferencia de los métodos analíticos, donde el concepto de límite es central y por tanto los procesos infinitos se manejan conjuntos de puntos discretos y haremos pasar por ellos o entre ellos un polinomio, para después integrar o derivar dicho polinomio. Con esta técnica podremos integrar y derivar funciones dadas tabularmente o bien funciones analíticas muy complejas e, incluso, integrar aq é as c a nt gra “no st ”, como s n caso de 76 s n cos s n tc Además, dicha técnica se puede aproximar a la obtención de integrales dobles y triples. Siendo la derivada la medida de cambio puntual o instantáneo y la integral la suma o acumulación de tales cambios, resulta fundamental en cualquier actividad de in-geniería o ciencias, conocer ambas técnicas, y no menos importante, darle sentido físico a los resultados. 4.2.- Simpson 1/3 Una forma de obtener una estimación más exacta de una integral consiste en usar polinomios de grado superior para unir los puntos. Por ejemplo, si hay otro punto a la mitad entre y los tres puntos se pueden unir con una parábola (figura 4.1a). Si hay dos puntos igualmente espaciados entre f(a) y f b , los cuatro puntos se pueden unir mediante un polinomio de tercer grado (figura 4.1b). Las fórmulas que resultan de tomar las integrales bajo esos polinomios se conocen como reglas de Simpson. La regla de Simpson 1/3 resulta cuando un polinomio de interpolación de segundo grado se sustituye en la siguiente ecuación: Figura 4.1a a) Descripción gráfica de la regla de Simpson 1/3, que consiste en tomar el área bajo una parábola que une tres puntos.
  • 81. 77 Figura 4.1b b) Descripción gráfica de la regla de Simpson 3/8 que consiste en tomar el área bajo una ecuación cubica que une cuatro puntos. 4.2.1.- Ejemplo propuesto Si se designan a y b como x0 y x2 respectivamente y f2(x) se representa por un polinomio de Lagrange de segundo grado, la integral se transforma en f f f Después de la integración y de las manipulaciones algebraicas, se obtiene la siguiente fórmula: f f f (Ec.4.1)
  • 82. donde, en este caso, . Esta ecuación se conoce como regla de Simpson 1/3, y es la segunda fórmula de integración cerrada de Newton-Cotes. La especificación "1/3" se origina del hecho de que está dividida entre 3 en la ecuación (Ec.4.1). Una alternativa para obtenerla se integra el polinomio de Newton- Gregory para llegar a la misma fórmula. 78 La regla de Simpson 1/3 también se puede expresar usando el formato de la siguiente ecuación: a b f f f (Ec.4.2) Ancho Altura promedio donde a b y el punto a la mitad entre a y b , que está dado por (b+a)/2. Observe que, de acuerdo con la ecuación (Ec.4.2), el punto medio está ponderado por dos tercios; y los dos puntos extremos, por un sexto. Se puede demostrar que la aplicación a un solo segmento de la regla de Simpson 1/3 tiene un error de truncamiento. t f o como t b a f (Ec.4.3) donde está en algún lugar en el intervalo de y Así, la regla de Simpson 1/3 es más exacta que la regla del trapecio. No obstante, una comparación con la ecuación (21.6) indica que es más exacta de lo esperado. En lugar de ser proporcional a la tercera derivada, el error es proporcional a la cuarta derivada. Esto es porque, como se muestra en el cuadro 21.3, el término del coeficiente de tercer grado se hace cero durante la integración de la interpolación polinomial. En consecuencia, la regla de Simpson 1/3 alcanza una precisión de tercer orden aun cuando se base en sólo tres puntos.
  • 83. 79 Aplicación simple de la regla de Simpson 1/3 Planteamiento del problema. Con la ecuación (Ec.4.2) integre desde hasta . Recuerde que la integral exacta es 1.640533 Solución. Por lo tanto, la ecuación (Ec.4.2.2) se utiliza para calcular Que representa un error exacto de que es aproximadamente 5 veces más precisa que una sola aplicación de la regla del trapecio El error estimado es [(Ec.4.2.2)] . donde -2400 es el promedio de la cuarta derivada en el intervalo, , debido a que el promedio de la cuarta derivada no es una estimación exacta de . Sin embargo, como este caso tiene que ver con un polinomio de quinto grado, el resultado concuerda.
  • 84. 80 4.2.2.- Diagrama de flujo INICIO n_s, n_p, h, b, a, x_j, j, k, i Diagrama de Flujo Simpson 1/3
  • 85. 81 4.2.3. - Pseudocódigo a) FUNCTION Simp13 (h, f0, fl, f2) simp13 = 2* h * (f0+4*f1+f2) /6 END Simp13 b) FUNCTION Simp38 (h, f0, fl, f2) simp38 = 3*h* (f0+3*(f1+f2)+f3) /8 END Simp38 c) FUNCION Simp13m (h, n, f) sum = f(0) DO i = 1, n- 2, 2 sum = sum + 4 * fi + 2 * fi+1 END DO sum = sum + 4 * fn-1 + 2 * fn simp13m = h * sum / 3 END Simp13m d) FUNCTION SimpInt (a, b, n, f) h = (b – a) / n IF n = 1 THEN sum = trap (h, fn-1,fn) ELSE m = n odd = n / 2 – INT(n / 2) IF odd > 0 AND > 1 THEN sum = sum + simp38(h, fn-3, fn-2, fn-1, fn) m = n – 3 END IF IF m > 1 THEN sum = sum + simp13m(h,m,f) END IF END IF SimpInt =sum END SimpInt
  • 86. 82 4.2.4.- Programas en C #include <stdio.h> /*para printf(),scanf()*/ #include <conio.h> /*para getch(),clrscr()*/ #include <stdlib.h>/*para exit()*/ #include <dos.h> #include <math.h> #define NUMEL 20 #define INTERVALOS 0 float f(float); void _error(int n); MAIN } h=(b-a)/(2*n); S0=S1=0; for(i=1;i<=(2*n-1);++i){ x=a+((double)i)*h; if(!(i%2)) S0+=f(x); else S1+=f(x); } *Area=(h*(f(a)+4*S1+2*S0+f(b))/3.0); printf("n El area es -> %5.6f",*Area); getch(); } void LeeDatos(int opc) { if(opc==SIMPSON1_3){ clrscr(); printf("n Metodo de Integracion por 1/3 de Simpson"); printf("n ========================================"); putchar('n'); printf("n Numero de intervalos (PAR) -> "); } scanf("%d",&n); if(n<1){ _error(INTERVALOS); exit(1); } else printf("n Valor de a =>"); scanf("%f",&a); printf("n Valor de b =>"); scanf("%f",&b); }
  • 87. 83 4.2.5.- Demostración del programa
  • 88. 84 COSTOS Para la elaboración de este manual de programas aplicados a métodos numéricos se recopiló información de diferentes fuentes: libros e internet pero como herramienta principal, el programa borland c++ versión 5.0 y el costo de operación de este software fue gratuito ya que la facultad cuenta con esta herramienta y está instalado en el centro de cómputo en nuestra facultad de ingeniería mecánica eléctrica.
  • 90. APORTACIONES Y CONTRIBUCIONES AL DESARROLLO Una de las razones por la que se elaboró este manual, es para que el estudiante tenga como apoyo en la experiencia de métodos numéricos, programas para aplicar los métodos, brindándoles así una herramienta que podrán utilizar y les permitirá ahorrar tiempo y esfuerzo. Con este trabajo práctico educativo se pretende que al estudiante le sea de mucha utilidad y disponga de una herramienta más, principalmente a los estudiantes de ingeniería que cursen la experiencia educativa de métodos numéricos con el fin de que logre una mayor comprensión de los temas mencionados, utilizando como estrategia de aprendizaje el uso de programas que ayuden a agilizar el procedimiento de los métodos expuestos en este tema. 86
  • 91. 87 BIBLIOGRAFÍA MÉTODOS NUMÉRICOS PARA INGENIEROS CON PROGRAMAS DE APLICACIÓN STEVEN C. CHAPRA RAYMOND P. CANALE MÉTODOS NUMÉRICOS LUTHE OLVERA SCHUTZ MÉTODOS NUMÉRICOS APLICADOS A LA INGENIERÍA ANTONIO NIEVES
  • 92. 88 ANEXOS Anexo A DIAGRAMAS DE FLUJO TERMINAL: Indica el inicio y el fin de un Diagrama de Flujo. DEFINICIÓN DE VARIABLES: Define todas y cada una de las variables que serán utilizadas en el programa representado en el diagrama de flujo. PROCESO: Cualquier tipo de operación que pueda originar cambio de valor, formato o posición de la información almacenada en memoria, operaciones aritméticas, de transferencia, etc. DECISIÓN: Indica operaciones lógicas o de comparación de datos, normalmente dos, y en función del resultado de la misma determina cual de los distintos caminos alternativos del programa se debe seguir; normalmente tiene dos salidas respuestas: sí o no, pero puede tener más según los casos. ENTRADA: Indica la asignación de un valor de una variable tomando este valor desde un dispositivo de entrada. SALIDA: Indica que el resultado será presentado ya sea por pantalla o por impresora.
  • 93. 89 Anexo B CICLOS Ciclos: Son procesos repetitivos los cuales se ejecutan una o más instrucciones varias veces. Valor Inicial: Se encuentra asignado a una variable la cual es la que controla el ciclo y debe ser de tipo entero, además tiene el valor de inicio del ciclo. Valor Final: Con este valor indicamos la última vez que el ciclo debe ejecutarse. Incremento: Representa la frecuencia en que debe aumentarse la variable. Entrada: Marca el principio o reinicio de las instrucciones que se encuentran dentro del ciclo. Regreso: Indica donde termina el ciclo, en qué momento el proceso se repite. Salida: Indica la finalización de la ejecución de un ciclo.
  • 94. 90 Anexo C PRINCIPIOS DE C En este anexo se ofrece una breve historia del desarrollo del lenguaje C y se consideran también sus características. ORÍGENES DEL C El proceso de desarrollo del lenguaje C se origina con la creación de un lenguaje llamado BCPL, que fue desarrollado por Martin Richards. El BCPL tuvo influencia en un lenguaje llamado B, el cual se usó en 1970 y fue inventado por Ken Thompson y que permitió el desarrollo de C en 1971, el cual lo inventó e implementó Dennis Ritchie. Para 1973 el sistema operativo UNIX estaba casi totalmente escrito en C. Durante muchos años el estándar para C fue la versión 5 del sistema operativo UNIX, documentada en ``The C Programming Language'' escrito por Brian W. Kernighan and Dennis M. Ritchie in 1978 comúnmente referido como K&R. Posteriormente se hicieron varias implementaciones las cuales mostraban las siguientes tendencias: Nuevas características Diferencias de máquinas Diferencias de productos Errores en los compiladores Malas implementaciones Esto originó que en el verano de 1983 se estableciera un comité para resolver estas discrepancias, el cual empezó a trabajar en un estándar ANSI C, la cual fue completada en 1988. CARACTERÍSTICAS DE C Algunas de las características más importantes que definen el lenguaje y que han permitido que sea tan popular, como lenguaje de programación son: Tamaño pequeño. Uso extensivo de llamadas a funciones. Comandos breves (poco tecleo). Lenguaje estructurado. Programación de bajo nivel (nivel bit) Implementación de apuntadores - uso extensivo de apuntadores para la memoria, arreglos, estructuras y funciones Las diversas razones por la cual se ha convertido en un lenguaje de uso profesional son: El uso de constructores de alto nivel. El poder manejar actividades de bajo-nivel. El generar programas eficientes. La posibilidad de poder ser compilado en una variedad de computadoras, con
  • 95. pocos cambios (portabilidad). Un punto en contra es que tiene una detección pobre de errores, lo cual en ocasiones es problemático para los principiantes. Estructura de un programa en C Un programa de C tiene básicamente la siguiente forma: Comandos del preprocesador. Definiciones de tipos. Prototipos de funciones - declara el tipo de función y las variables pasadas a la misma. Variables Funciones Para un programa se debe tener una función main(). Una función tiene la forma: tipo nombre_de_la_funcion (parámetros) { 91 variables locales sentencias de C } Si la definición del tipo es omitida, C asume que la función regresa un tipo entero. Nota: Lo anterior puede ser una fuente de problemas en un programa. A continuación se muestra un primer programa: /* Programa ejemplo */ main() { printf( "Me gusta Cn" ); exit (0); } NOTAS: C requiere un punto y coma al final de cada sentencia. printf es una función estándar de C, la cual es llamada en la función main(). n significa salto de línea. Salida formateada. exit() es también una función estándar que hace que el programa termine. En el sentido estricto no es necesario ya que es la última línea de main() y de cualquier forma terminará el programa. En caso de que se hubiera llamado a la función printf de la siguiente forma: printf(".n.1n..2n...3n"); La salida tendría la siguiente forma: .1 ..2 ...3
  • 96. 92 VARIABLES C tiene los siguientes tipos de datos simples: Tabla: Tipos de C Tipo Tamaño (bytes) Límite inferior Límite superior Char 1 -- -- unsigned char 1 short int 2 unsigned short int 2 (long) int 4 Float 4 double 8 Los tipos de datos básicos tiene varios modificadores que les preceden. Se usa un modificador para alterar el significado de un tipo base para que encaje con las diversas necesidades o situaciones. Los modificadores son: signed, unsigned, long y short. En los sistemas UNIX todos los tipos int son long int, a menos que se especifique explícitamente short int. Nota: no hay un tipo booleano en C -- se deberá usar char, int o aún mejor unsigned char. signed, unsigned, long y short pueden ser usados con los tipos char e int. Aunque es permitido el uso de signed en enteros, es redundante porque la declaración de entero por defecto asume un número con signo. Para declarar una variable en C, se debe seguir el siguiente formato: tipo lista_variables; tipo es un tipo válido de C y lista_variables puede consistir en uno o más identificadores separados por una coma. Un identificador debe comenzar con una letra o un guión bajo. Ejemplo: int i, j, k; float x,y,z; char ch;
  • 97. 93 DEFINICIÓN DE VARIABLES GLOBALES Una variable global se declara fuera de todas las funciones, incluyendo a la función main(). Una variable global puede ser utilizada en cualquier parte del programa. Por ejemplo: short numero, suma; int numerogr, sumagr; char letra; main() { ... } Es también posible pre inicializar variables globales usando el operador de asignación =, por ejemplo: float suma= 0.0; int sumagr= 0; char letra= 'A'; main() { ... } Que es lo mismo que: float suma; int sumagr; char letra; main() { suma = 0.0; sumagr= 0; letra = 'A'; ... } Dentro de C también se permite la asignación múltiple usando el operador =, por ejemplo: a = b = c = d = 3; ...que es lo mismo, pero más eficiente que: a = 3; b = 3; c = 3;
  • 98. 94 d = 3; La asignación múltiple se puede llevar a cabo, si todos los tipos de las variables son iguales. Se pueden redefinir los tipos de C usando typedef. Como un ejemplo de un simple uso se considera como se crean dos nuevos tipos real y letra. Estos nuevos tipos pueden ser usados de igual forma como los tipos predefinidos de C. typedef float real; typedef char letra; /* Declaración de variables usando el nuevo tipo */ real suma=0.0; letra sig_letra; LECTURA Y ESCRITURA DE VARIABLES El lenguaje C usa salida formateada. La función printf tiene un carácter especial para formatear (%) -- un carácter enseguida define un cierto tipo de formato para una variable. %c caracteres %s cadena de caracteres %d enteros %f flotantes Por ejemplo: printf("%c %d %f",ch,i,x); La sentencia de formato se encierra entre " ", y enseguida las variables. Asegurarse que el orden de formateo y los tipos de datos de las variables coincidan. scanf() es la función para entrar valores a variables. Su formato es similar a printf. Por ejemplo: scanf("%c %d %f %s",&ch, &i, &x, cad); Observar que se antepone & a los nombres de las variables, excepto a la cadena de caracteres. CONSTANTES ANSI C permite declarar constantes. Cuando se declara una constante es un poco parecido a declarar una variable, excepto que el valor no puede ser cambiado. La palabra clave const se usa para declarar una constante, como se muestra a continuación: const a = 1; int a = 2; Notas: Se puede usar constantes o después del tipo.
  • 99. Es usual inicializar una constante con un valor, ya que no puede ser cambiada de alguna otra forma. La directiva del preprocesador #define es un método más flexible para definir constantes en un programa. Frecuentemente se ve la declaración const en los parámetros de la función. Lo anterior simplemente indica que la función no cambiara el valor del parámetro. Por ejemplo, la siguiente función usa este concepto: char *strcpy(char *dest, const char *orig); El segundo argumento orig es una cadena de C que no será alterada, cuando se use la función de la biblioteca para copiar cadenas. 95 OPERADORES ARITMÉTICOS Lo mismo que en otros lenguajes de programación, en C se tienen los operadores aritméticos más usuales (+ suma, - resta, * multiplicación, / división y % módulo). El operador de asignación es =, por ejemplo: i=4; ch='y'; Incremento ++ y decremento -- unario. Los cuales son más eficientes que las respectivas asignaciones. Por ejemplo: x++ es más rápido que x=x+1. Los operadores ++ y -- pueden ser prefijos o postfijos. Cuando son prefijos, el valor es calculado antes de que la expresión sea evaluada, y cuando es postfijo el valor es calculado después que la expresión es evaluada. En el siguiente ejemplo, ++z es prefijo y -- es postfijo: int x,y,z; main() { x=( ( ++z ) - ( y-- ) ) % 100; } Que es equivalente a: int x,y,z; main() { z++; x = ( z-y ) % 100; y--; } El operador % (módulo o residuo) solamente trabaja con enteros, aunque existe una función para flotantes. El operador división / es para división entera y flotantes. Por lo tanto hay que tener cuidado. El resultado de x = 3 / 2; es uno, aún si x es declarado como float. La regla es: si ambos argumentos en una división son enteros, entonces el resultado es entero. Si se desea obtener la división con la fracción, entonces escribirlo como: x = 3.0 / 2; o x = 3 / 2.0 y aún mejor x = 3.0 / 2.0. Por otra parte, existe una forma más corta para expresar cálculos en C. Por ejemplo, si se tienen expresiones como: i = i + 3; o x = x * (y + 2); , pueden ser
  • 100. 96 reescritas como: Lo cual es equivalente, pero menos eficiente que: Por lo que podemos reescribir las expresiones anteriores como: i += 3; y x *= y + 2; respectivamente. OPERADORES DE COMPARACIÓN El operador para probar la igualdad es ==, por lo que se deberá tener cuidado de no escribir accidentalmente sólo =, ya que: if ( i = j ) ... Es una sentencia legal de C (sintácticamente hablando aunque el compilador avisa cuando se emplea), la cual copia el valor de ``j'' en ``i'', lo cual será interpretado como VERDADERO, si j es diferente de cero. Diferente es !=, otros operadores son: < menor que, > mayor que, <= menor que o igual a y >= (mayor que o igual a). OPERADORES LÓGICOS Los operadores lógicos son usualmente usados con sentencias condicionales o relacionales, los operadores básicos lógicos son: && Y lógico, || O lógico y! negación. ORDEN DE PRECEDENCIA Es necesario ser cuidadosos con el significado de expresiones tales como a + b * c, dependiendo de lo que se desee hacer (a + b) * c o a + (b * c) Todos los operadores tienen una prioridad, los operadores de mayor prioridad son evaluados antes que los que tienen menor prioridad. Los operadores que tienen la misma prioridad son evaluados de izquierda a derecha, por lo que: a - b - c es evaluado como (a - b) - c Prioridad Operador(es) Más alta ( ) [ ] -> ! ~ ++ -- - (tipo) * & sizeof * / % + -
  • 101. 97 << >> < <= > >= == != & ^ | && || ? = += -= *= /= Más baja , De acuerdo a lo anterior, la siguiente expresión: a < 10 && 2 * b < c Es interpretada como: (a < 10) && ( (2 * b) < c ) y a = b = 10 / 5 + 2; como a = ( b = ( 10 / 5 ) + 2 ); ESTRUCTURAS CONDICIONALES En este capítulo se revisan los distintos métodos con los que C controla el flujo lógico de un programa. Como se revisó en el capítulo anterior, los operadores relaciones binarios que se usan son: ==, !=, <, <=, > y >= además los operadores lógicos binarios: ||, && y el operador lógico unario de negación !, que sólo toma un argumento. Los operadores anteriores son usados con las siguientes estructuras que se muestran.
  • 102. 98 LA SENTENCIA IF Las tres formas como se puede emplear la sentencia if son: if (condición) sentencia; ...o if (condición) sentencia1; else sentencia2; ...o if (condicion1) sentencia1; else if (condicion2) sentencia2; ... else sentencian; El flujo lógico de esta estructura es de arriba hacia abajo. La primera sentencia se ejecutará y se saldrá de la estructura if si la primera condición es verdadera. Si la primera condición fue falsa, y existe otra condición, se evalúa, y si la condición es verdadera, entonces se ejecuta la sentencia asociada. Si existen más condiciones dentro de la estructura if, se van evaluando éstas, siempre y cuando las condiciones que le precedan sean falsas. La sentencia que está asociada a la palabra reservada else, se ejecuta si todas las condiciones de la estructura if fueron falsas. Por ejemplo: main() { int x, y, w; ........ if (x>0) { z=w; ....... } else { z=y; ....... } }
  • 103. 99 EL OPERADOR “?” El operador ternario condicional “?” es más eficiente que la sentencia if. El operador ? tiene el siguiente formato: expresión1 ? expresión 2 : expresion3; Que es equivalente a la siguiente expresión: if (expresión1) then expresión2 else expresión3; Por ejemplo, para asignar el máximo de a y b a la variable z, usando ?, tendríamos: z = (a>b) ? a : b; que es lo mismo que: if (a > b) z = a; else z = b; El uso del operador “?” para reemplazar las sentencias if ... else no se restringe sólo a asignaciones, como en el ejemplo anterior. Se pueden ejecutar una o más llamadas de función usando el operador ? poniéndolas en las expresiones que forman los operandos, como en el ejemplo siguiente: f1(int n) { printf("%d ",n); } f2() { printf("introducidon"); } main() { int t; printf(": "); scanf("%d",&t); /* imprime mensaje apropiado */ t ? f1(t) + f2() : printf("Se dio un ceron"); }
  • 104. 100 LA SENTENCIA SWITCH Aunque con la estructura if ... else if se pueden realizar comprobaciones múltiples, en ocasiones no es muy elegante, ya que el código puede ser difícil de seguir y puede confundir incluso al autor transcurrido un tiempo. Por lo anterior, C tiene incorporada una sentencia de bifurcación múltiple llamada switch. Con esta sentencia, la computadora comprueba una variable sucesivamente frente a una lista de constantes enteras o de carácter. Después de encontrar una coincidencia, la computadora ejecuta la sentencia o bloque de sentencias que se asocian con la constante. La forma general de la sentencia switch es: switch (variable) { case constante1: secuencia de sentencias break; case constante2: secuencia de sentencias break; case constante3: secuencia de sentencias break; ... default: secuencia de sentencias } Donde la computadora ejecuta la sentencia default si no coincide ninguna constante con la variable, esta última es opcional. Cuando se encuentra una coincidencia, la computadora ejecuta las sentencias asociadas con el case hasta encontrar la sentencia break con lo que sale de la estructura switch. Las limitaciones que tiene la sentencia switch ... case respecto a la estructura if son: Sólo se tiene posibilidad de revisar una sola variable. Con switch sólo se puede comprobar por igualdad, mientras que con if puede ser con cualquier operador relacional. No se puede probar más de una constante por case. La forma como se puede simular el último punto, es no teniendo sentencias asociados a un case, es decir, teniendo una sentencia nula donde sólo se pone el caso, con lo que se permite que el flujo del programa caiga al omitir las sentencias, como se muestra a continuación: switch (letra) { case 'a': case 'e': case 'i': case 'o': case 'u': numvocales++; break;
  • 105. 101 case ' ': numesp++; break; default: numotras++; break; } ITERACIÓN En este capítulo se revisan los mecanismos de C para repetir un conjunto de instrucciones hasta que se cumple cierta condición. LA SENTENCIA FOR La sentencia for tiene el siguiente formato: for ( expresión1; expresión2; expresión3) sentencia; o { bloque de sentencias } En donde expresión1 se usa para realizar la inicialización de variables, usando una o varias sentencias, si se usan varias sentencias deberá usarse el operador, para separarlas. Por lo general, establece el valor de la variable de control del ciclo. expresión2 se usa para la condición de terminación del ciclo y expresión3 es el modificador a la variable de control del ciclo cada vez que la computadora lo repite, pero también puede ser más que un incremento. Por ejemplo: int X; main() { for( X=3; X>0; X--) { printf("X=%dn",X); } } genera la siguiente salida a pantalla ... X=3 X=2 X=1
  • 106. Todos las siguientes sentencias for son válidas en C. Las aplicaciones prácticas de tales sentencias no son importantes aquí, ya que tan sólo se intenta ilustrar algunas características que pueden ser de utilidad: for ( x=0; ( (x>3) && (x<9) ); x++ ) 102 for ( x=0, y=4; ( (x>3) && (x<9) ); x++, y+=2) for ( x=0, y=4, z=4000; z; z/=10) En el segundo ejemplo se muestra la forma como múltiples expresiones pueden aparecer, siempre y cuando estén separadas por una coma , En el tercer ejemplo, el ciclo continuará iterando hasta que z se convierta en . LA SENTENCIA WHILE La sentencia while es otro ciclo o bucle disponible en C. Su formato es: while ( expresión) sentencia; donde sentencia puede ser una sentencia vacía, una sentencia única o un bloque de sentencias que se repetirán. Cuando el flujo del programa llega a esta instrucción, primero se revisa si la condición es verdad para ejecutar la(s) sentencia(s), y después el ciclo while se repetirá mientras la condición sea verdadera. Cuando llega a ser falsa, el control del programa pasa a la línea que sigue al ciclo. En el siguiente ejemplo se muestra una rutina de entrada desde el teclado, la cual se cicla mientras no se pulse A: main() { char carac; carac = '0'; while( carac != 'A') carac = getchar(); } Antes de entrar al ciclo se inicializa la variable carac a nulo. Después pasa a la sentencia while donde se comprueba si carac no es igual a 'A', como sea verdad entonces se ejecuta la sentencia del bucle (carac = getchar();). La función getchar() lee el siguiente carácter del flujo estándar (teclado) y lo devuelve, que en nuestro ejemplo es el caracter que haya sido tecleado. Una vez que se ha pulsado una tecla, se asigna a carac y se comprueba la condición nuevamente. Después de pulsar A, la condición llega a ser falsa porque carac es igual a A, con lo que el ciclo termina. De lo anterior, se tiene que tanto el ciclo for, como el ciclo while comprueban la condición en lo alto del ciclo, por lo que el código dentro del ciclo no se ejecuta siempre.
  • 107. 103 A continuación mostramos otro ejemplo: main() { int x=3; while( x>0 ) { printf("x = %dn", x); x--; } } que genera la siguiente salida en pantalla: x = 3 x = 2 x = 1 Como se observa, dentro del ciclo tenemos más de una sentencia, por lo que se requiere usar la llave abierta y la llave cerrada { ... } para que el grupo de sentencias sean tratadas como una unidad. Como el ciclo while pueda aceptar también expresiones, y no solamente condiciones lo siguiente es válido: while ( x-- ); while ( x = x + 1 ); while ( x += 5 ); Si se usan este tipo de expresiones, solamente cuando el resultado de x--, x=x+1 o x+=5 sea cero, la condición fallará y se podrá salir del ciclo. De acuerdo a lo anterior, podemos realizar una operación completa dentro de la expresión. Por ejemplo: main() { char carac; carac = '0'; while ( (carac = getchar()) != 'A' ) putchar(carac); } En este ejemplo se usan las funciones de la biblioteca estándar getchar() -- lee un carácter del teclado y putchar() escribe un carácter dado en pantalla. El ciclo while procederá a leer del teclado y lo mostrará hasta que el carácter A sea leído. LA SENTENCIA DO-WHILE Al contrario de los ciclos for y while que comprueban la condición en lo alto del bucle, el bucle do ... while la examina en la parte baja del mismo. Esta característica provoca que un ciclo do ... while siempre se ejecute al menos una
  • 108. 104 vez. La forma general del ciclo es: do { sentencia; } while (condición); Aunque no son necesarias las llaves cuando sólo está presente una sentencia, se usan normalmente por legibilidad y para evitar confusión (respecto al lector, y no del compilador) con la sentencia while. En el siguiente programa se usa un ciclo do ... while para leer números desde el teclado hasta que uno de ellos es menor que o igual a 100: main() { int num; do { scanf("%d", &num); } while ( num>100 ); } Otro uso común de la estructura do... while es una rutina de selección en un menú, ya que siempre se requiere que se ejecute al menos una vez. main() { int opc; printf("1. Derivadasn"); printf("2. Limitesn"); printf("3. Integralesn"); do { printf(" Teclear una opcion: "); scanf("%d", &opc); switch(opc) { case 1: printf("tOpcion 1 seleccionadann"); break; case 2: printf("tOpcion 2 seleccionadann"); break; case 3: printf("tOpcion 3 seleccionadann"); break; default: printf("tOpcion no disponiblenn"); break; }
  • 109. 105 } while( opc != 1 && opc != 2 && opc != 3); } Se muestra un ejemplo donde se reescribe usando do... while uno de los ejemplos ya mostrados. main() { int x=3; do { printf("x = %dn", x--); } while( x>0 ) ; } USO DE BREAK Y CONTINUE Como se comento uno de los usos de la sentencia break es terminar un case en la sentencia switch. Otro uso es forzar la terminación inmediate de un ciclo, saltando la prueba condicional del ciclo. Cuando se encuentra la sentencia break en un bucle, la computadora termina inmediatamente el ciclo y el control del programa pasa a la siguiente sentencia del ciclo. Por ejemplo: main() { int t; for(t=0; t<100; t++) { printf("%d ", t); if (t==10) break; } } Este programa muestra en pantalla los números del 0 al 10, cuando alcanza el valor 10 se cumple la condición de la sentencia if, se ejecuta la sentencia break y sale del ciclo. La sentencia continue funciona de manera similar a la sentencia break. Sin embargo, en vez de forzar la salida, continue fuerza la siguiente iteración, por lo que salta el código que falta para llegar a probar la condición. Por ejemplo, el siguiente programa visualizará sólo los números pares: main() { int x; for( x=0; x<100; x++) { if (x%2) continue; printf("%d ",x);
  • 110. 106 } } Finalmente se considera el siguiente ejemplo donde se leen valores enteros y se procesan de acuerdo a las siguientes condiciones. Si el valor que sea leído es negativo, se desea imprimir un mensaje de error y se abandona el ciclo. Si el valor es mayor que 100, se ignora y se continúa leyendo, y si el valor es cero, se desea terminar el ciclo. main() { int valor; while( scanf("%d", &valor) == 1 && valor != 0) { if ( valor<0 ) { printf("Valor no validon"); break; /* Salir del ciclo */ } if ( valor>100) { printf("Valor no validon"); continue; /* Pasar al principio del ciclo nuevamente */ } printf("Se garantiza que el valor leido esta entre 1 y 100"); } } ARREGLOS UNIDIMENSIONALES Y MULTIDIMENSIONALES Los arreglos son una colección de variables del mismo tipo que se referencian utilizando un nombre común. Un arreglo consta de posiciones de memoria contigua. La dirección más baja corresponde al primer elemento y la más alta al último. Un arreglo puede tener una o varias dimensiones. Para acceder a un elemento en particular de un arreglo se usa un índice. El formato para declarar un arreglo unidimensional es: tipo nombre_arr [ tamaño ] Por ejemplo, para declarar un arreglo de enteros llamado listanum con diez elementos se hace de la siguiente forma: int listanum[10]; En C, todos los arreglos usan cero como índice para el primer elemento. Por tanto, el ejemplo anterior declara un arreglo de enteros con diez elementos desde listanum[0] hasta listanum[9]. La forma como pueden ser accesados los elementos de un arreglo, es de la siguiente forma:
  • 111. 107 listanum[2] = 15; /* Asigna 15 al 3er elemento del arreglo listanum*/ num = listanum[2]; /* Asigna el contenido del 3er elemento a la variable num */ El lenguaje C no realiza comprobación de contornos en los arreglos. En el caso de que sobrepase el final durante una operación de asignación, entonces se asignarán valores a otra variable o a un trozo del código, esto es, si se dimensiona un arreglo de tamaño N, se puede referenciar el arreglo por encima de N sin provocar ningún mensaje de error en tiempo de compilación o ejecución, incluso aunque probablemente se provoque el fallo del programa. Como programador se es responsable de asegurar que todos los arreglos sean lo suficientemente grandes para guardar lo que pondrá en ellos el programa. C permite arreglos con más de una dimensión, el formato general es: tipo nombre_arr [ tam1 ][ tam2 ] ... [ tamN]; Por ejemplo un arreglo de enteros bidimensionales se escribirá como: int tabladenums[50][50]; Observar que para declarar cada dimensión lleva sus propios paréntesis cuadrados. Para acceder los elementos se procede de forma similar al ejemplo del arreglo unidimensional, esto es, tabladenums[2][3] = 15; /* Asigna 15 al elemento de la 3ª fila y la 4ª columna*/ num = tabladenums[25][16]; A continuación se muestra un ejemplo que asigna al primer elemento de un arreglo bidimensional cero, al siguiente 1, y así sucesivamente. main() { int t,i,num[3][4]; for(t=0; t<3; ++t) for(i=0; i<4; ++i) num[t][i]=(t*4)+i*1; for(t=0; t<3; ++t) { for(i=0; i<4; ++i) printf("num[%d][%d]=%d ", t,i,num[t][i]); printf("n"); } } En C se permite la inicialización de arreglos, debiendo seguir el siguiente formato: tipo nombre_arr[ tam1 ][ tam2 ] ... [ tamN] = {lista-valores}; Por ejemplo: int i[10] = {1,2,3,4,5,6,7,8,9,10}; int num[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
  • 112. 108 CADENAS A diferencia de otros lenguajes de programación que emplean un tipo denominado cadena string para manipular un conjunto de símbolos, en C, se debe simular mediante un arreglo de caracteres, en donde la terminación de la cadena se debe indicar con nulo. Un nulo se especifica como '0'. Por lo anterior, cuando se declare un arreglo de caracteres se debe considerar un carácter adicional a la cadena más larga que se vaya a guardar. Por ejemplo, si se quiere declarar un arreglo cadena que guarde una cadena de diez caracteres, se hará como: char cadena[11]; Se pueden hacer también inicializaciones de arreglos de caracteres en donde automáticamente C asigna el carácter nulo al final de la cadena, de la siguiente forma: char nombre_arr[ tam ]="cadena"; Por ejemplo, el siguiente fragmento inicializa cadena con ``hola'': char cadena[5]="hola"; El código anterior es equivalente a: char cadena[5]={'h','o','l','a','0'}; Para asignar la entrada estándar a una cadena se puede usar la función scanf con la opción %s (observar que no se requiere usar el operador &), de igual forma para mostrarlo en la salida estándar. Por ejemplo: main() { char nombre[15], apellidos[30]; printf("Introduce tu nombre: "); scanf("%s",nombre); printf("Introduce tus apellidos: "); scanf("%s",apellidos); printf("Usted es %s %sn",nombre,apellidos); } El lenguaje C no maneja cadenas de caracteres, como se hace con enteros o flotantes, por lo que lo siguiente no es válido: main() { char nombre[40], apellidos[40], completo[80]; nombre="José María"; /* Ilegal */ apellidos="Morelos y Pavón"; /* Ilegal */ completo="Gral."+nombre+apellidos; /* Ilegal */ } Funciones Una función es un conjunto de declaraciones, definiciones, expresiones y sentencias que realizan una tarea específica.
  • 113. 109 El formato general de una función en C es: especificador_de_tipo nombre_de_función( lista_de_parámetros ) { variables locales código de la función } El especificador_de_tipo indica el tipo del valor que la función devolverá mediante el uso de return. El valor puede ser de cualquier tipo válido. Si no se específica un valor, entonces la computadora asume por defecto que la función devolverá un resultado entero. No se tienen siempre que incluir parámetros en una función. la lista de parámetros puede estar vacía. Las funciones terminan y regresan automáticamente al procedimiento que las llamó cuando se encuentra la última llave}, o bien, se puede forzar el regreso antes usando la sentencia return. Además del uso señalado la función return se usa para devolver un valor. Se examina a continuación un ejemplo que encuentra el promedio de dos enteros: float encontprom(int num1, int num2) { float promedio; promedio = (num1 + num2) / 2.0; return(promedio); } main() { int a=7, b=10; float resultado; resultado = encontprom(a, b); printf("Promedio=%fn",resultado); } FUNCIONES VOID Las funciones void dan una forma de emular, lo que en otros lenguajes se conocen como procedimientos (por ejemplo, en PASCAL). Se usan cuando no requiere regresar un valor. Se muestra un ejemplo que imprime los cuadrados de ciertos números. void cuadrados() { int contador; for( contador=1; contador<10; contador++) printf("%dn",contador*contador); } main() {
  • 114. 110 cuadrados(); } En la función cuadrados no está definido ningún parámetro, y por otra parte tampoco se emplea la sentencia return para regresar de la función. FUNCIONES Y ARREGLOS Cuando se usan un arreglo como un argumento a la función, se pasa sólo la dirección del arreglo y no la copia del arreglo entero. Para fines prácticos podemos considerar el nombre del arreglo sin ningún índice como la dirección del arreglo. Considerar el siguiente ejemplo en donde se pasa un arreglo a la función imp_rev, observar que no es necesario especificar la dimensión del arreglo cuando es un parámetro de la función. void imp_rev(char s[]) { int t; for( t=strlen(s)-1; t>=0; t--) printf("%c",s[t]); } main() { char nombre[]="Facultad"; imp_rev(nombre); } Observar que en la función imp_rev se usa la función strlen para calcular la longitud de la cadena sin incluir el terminador nulo. Por otra parte, la función imp_rev no usa la sentencia return ni para terminar de usar la función, ni para regresar algún valor. Se muestra otro ejemplo, float enconprom(int tam, float lista[]) { int i; float suma = 0.0; for ( i=0; i<tam; i++) suma += lista[i]; return(suma/tam); } main() { float numeros[]={2.3, 8.0, 15.0, 20.2, 44.01, -3.0, -2.9}; printf("El promedio de la lista es %fn", enconprom(7,numeros) ); }