Documentos de Académico
Documentos de Profesional
Documentos de Cultura
File... Action... Data... sage Typeset Load 3-D Live Use java for 3-D
Print Worksheet Edit Text Revisions Share Publish
Entrega de la práctica: Desde el 12 de diciembre hasta el 19 de diciembre (ver tarea en el campus virtual
o agenda de la asignatura)
Instrucciones:
Para cambiar el nombre pulsa en el título de la hoja (arriba del todo, entre el logo de Sage y el menú
"Archivo/File...")
4. Cuando hayas terminado, haz una copia en un único fichero PDF y ponlo en el campus virtual (Si lo
hacéis en pareja, basta que lo suba uno). Esa será la versión que se evaluará. La hoja no se considera
entregada si no se ha renombrado y compartido (pasos 1 y 2).
Para generar el PDF lo más sencillo es usar el botón Imprimir/Print de arriba e imprimir la nueva
página a fichero.
5. Una vez subido el PDF al campus virtual, no podrá modificarse esta hoja de trabajo. Hacerlo conllevará
la calificación de 0 en esta práctica.
6. Los ejercicios a entregar se representan en Rojo y deben estar correctamente explicados. Los ejercicios
indicados con ** NO serán obligatorios, pero aquellos que los hagan podrán ir sumando por cada uno de
ellos 0.1 puntos adicionales en la calificación de la práctica.
f(x) = - x + cos(x)
print "f(x) = ", f(x)
f(x) = -x + cos(x)
a, b = 0,1
plot(f(x),(x,a,b),figsize=4)
f(x) = − x + cos(x)
presenta una raíz en el intervalo [0,1], pues se cumplen las condiciones del Teorema de Bolzano. En Sage,
se puede encontrar la raíz de una función, f(x), en un intervalo [a, b] utilizando la función
find_root(f(x),a,b). Recordemos, además, que encontrar una raíz de una función no es más que resolver la
ecuación
f(x) = 0
, por lo que podemos aplicar también la función solve(f(x)==0,x), donde el primer argumento es la
ecuación a resolver (o varias ecuaciones), y el segundo argumento es la incógnita (o incógnitas).
find_root(f(x),a,b)
0.7390851332151559
solve(f(x)==0,x)
[x == cos(x)]
Sin embargo, observamos que esta última opción nos muestra que esta ecuación no tiene una solución
exacta, por lo que habría que aplicar métodos numéricos para resolverla, o equivalentemente, la función no
tiene una raíz exacta y se debe aproximar, y por lo tanto, se debe asumir un cierto error.
En métodos numéricos es necesario indicar el límite de error que podemos cometer (o asumir) para
encontrar una aproximación de la raíz buscada. Por ello, si llamamos error al error que se comete al aplicar
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 2/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
un método numérico y err al error permitido que podemos asumir al aproximar la raíz, se debe cumplir que
error ≤ err
error ≤ err
Situación 2. Que la raíz buscada tenga una precisión de d cifras decimales significativas, con lo cual, el
error permitido en este caso es
err = 0.5 ⋅ 10 − d
y por tanto,
error ≤ 0.5 ⋅ 10 − d
En particular, un primer método numérico es el método de la Bisección que consiste en encontrar la raíz de
una función en un intervalo [a, b] en el que la función cumple el Teorema de Bolzano, de tal modo que la
raíz considerada es el punto medio del intervalo
a+b
c=
2
c = (a+b)/2.0
print "La aproximación de la raíz es:", c
La aproximación de la raíz es: 0.500000000000000
Como vemos con una primera iteración la aproximación de la raíz es bastante mala, teniendo en cuenta
cuál era el valor de la verdadera raíz mostrada anteriormente. Es por ello, que debemos hacer más
iteraciones para encontrar una mejor aproximación de la raíz. Por ejemplo, creemos un bucle (for) en el que
apliquemos el método de la Bisección n veces, por ejemplo n = 5.
n = 5
for i in [1..n]:
print "Iteración:", i
print "Intervalo:", (a,b)
print "f(a) = ", f(a).n(digits=4)
print "f(b) = ", f(b).n(digits=4)
c = (a+b)/2.0
print "Aproximación de la raíz:", c.n(digits=4)
print "f(c) = ", f(c).n(digits=4)
if f(a)*f(c)<0: b = c
else: a = c
print
Iteración: 1
Intervalo: (0, 1)
f(a) = 1.000
f(b) = -0.4597
Aproximación de la raíz: 0.5000
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 3/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
f(c) = 0.3776
Iteración: 2
Intervalo: (0.500000000000000, 1)
f(a) = 0.3776
f(b) = -0.4597
Aproximación de la raíz: 0.7500
f(c) = -0.01831
Iteración: 3
Intervalo: (0.500000000000000, 0.750000000000000)
f(a) = 0.3776
f(b) = -0.01831
Aproximación de la raíz: 0.6250
f(c) = 0.1860
Iteración: 4
Intervalo: (0.625000000000000, 0.750000000000000)
f(a) = 0.1860
f(b) = -0.01831
Aproximación de la raíz: 0.6875
f(c) = 0.08533
Iteración: 5
Intervalo: (0.687500000000000, 0.750000000000000)
f(a) = 0.08533
f(b) = -0.01831
Aproximación de la raíz: 0.7188
f(c) = 0.03388
Observamos que con 5 iteraciones, hemos encontrado una aproximación de la raíz de 0.7188, ya más
próxima al verdadero valor de la raíz. En relación al error, en el método de la Bisección, si se quiere buscar
una raíz de una función en el intervalo [a, b], el error que se comete en la iteración n es:
b−a
error n =
2n
1−0
error 5 =
25
a,b,n = 0,1,5
error = (b-a)/2^n; print "Error cometido:", error.n(digits=4)
Error cometido: 0.03125
De manera general, si se debe cumplir que el error cometido sea inferior al error permitido, entonces
error n ≤ err
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 4/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
luego,
b−a
≤ err
2n
n≥
log
( )
b−a
err
log2
De forma que para encontrar una raíz de la función f(x) en el intervalo [a, b] cuyo error cometido sea
inferior al error permitido err es necesario realizar n iteraciones, donde n debe ser mayor o igual a
log ( )
b−a
err
log2
Por tanto, veamos cuántas iteraciones (n) son necesarias para encontrar una raíz de la función
f(x) = − x + cos(x) en el intervalo [0, 1] con un error permitido err = 0.05.
Además, vemos que el valor de n debe ser mayor o igual a 4.32, y como n es el número de iteraciones, y
por tanto un número entero, debemos redondear por exceso este último valor, por lo que utilizaremos la
función .ceil().
n = n.ceil()
print "Iteraciones necesarias:", n
Iteraciones necesarias: 18
Por otro lado, si queremos una aproximación de la raíz con una precisión de d = 5 cifras decimales
significativas, entonces el error permitido será
error n ≤ 0.5 ⋅ 10 − 5
por tanto
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 5/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
Ejercicio 1. Crea una función que aplique el método de la Bisección para encontrar
una aproximación de la raíz de una función f(x) en un intervalo [a, b] cuyo error
permitido sea err, por ello la función debe recibir como argumentos f(x), los valores
a, b y el error err, y debe devolver la aproximación encontrada de la raíz, c, y el error
que se ha cometido al encontrarla.
En primer lugar calculamos el número de iteraciones necesarias mediante la fórmula que se incluye
en el código.
Finalmente calculamos la aproximación, para ello creamos un bucle que se ejecute para cada
iteración y que consiste en:
2. Realizar su producto, esto nos sirve para averiguar si si signo es igual (el producto saldría
positivo) o si son distintos (producto negativo).
Signo positivo: Se vuelve a realizar el bucle entre el centro previamente calculado y b (a=c)
Signo negativo: Se vuelve a realizar el bucle entre el centro previamente calculado y a
(b=c)
def Biseccion(f,a,b,err):
n = log((b-a)/err)/log(2.0)
n=n.ceil()
print "Iteraciones necesarias:", n
error = (b-a)/2^n
print "Error cometido:", error.n(digits=4)
for i in [0..n-1]:
c=(a+b)/2.0
z=f(c)*f(a)
if z>0:
a=c
else:
b=c
print "Aproximacion: ",c
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 6/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
( (
f(x) = e − x − sin x ⋅ 1 +
1
log(dni) ))
siendo dni la suma de los números de tu DNI. Aplicando la función creada en el
ejercicio anterior, encuentra una aproximación de la raíz de la función en el intervalo
[0, 1] con una precisión de 5 cifras decimales significativas.
f(x)=e^(-x)-sin(x*(1+((1)/(log(24.0)))))
a, b = 0,1
plot(f(x),(x,a,b),figsize=4,color='orange',thickness=2)
Según el Teorema de Bolzano, si nos fijamos en la gráfica anterior observamos que al cambiar de
signo en el intervalo [0,1], existe una raíz en este intervalo, por lo que podemos realizar el método de
la bisección entre estos dos puntos.
f=f(x)
err=0.5*10^(-5)
Biseccion(f,0,1,err)
Iteraciones necesarias: 18
Error cometido: 3.815e-6
Aproximacion: 0.497287750244141
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 7/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
aplica el método de la Bisección para encontrar una solución de la ecuación con una
precisión de 4 cifras decimales significativas.
f(x)=x*sin(x)+2*ln(x)+x-2.6
a, b = 1,2
plot(f(x),(x,a,b),figsize=4,color='purple',thickness=2)
Según el Teorema de Bolzano, si nos fijamos en la gráfica anterior observamos que cambia de signo
en el intervalo [1,2], por lo que existe una raíz en este intervalo. Este intervalo lo hemos encontrando
probando valores.
f=f(x)
err=0.5*10^(-4)
Biseccion(f,1,2,err)
Iteraciones necesarias: 15
Error cometido: 0.00003052
Aproximacion: 1.17947387695312
f(x) = 80 ⋅ e − 2x + 20 ⋅ e − 0.5x − 5
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 8/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
f(x)=80*e^(-2*x)+20*e^(-0.5*x)-5
a, b = 2,3
plot(f(x),(x,a,b),figsize=4,color='green',thickness=2)
Según el Teorema de Bolzano, si nos fijamos en la gráfica anterior observamos que cambia de signo
en el intervalo [2,3], por lo que existe una raíz en este intervalo. Este intervalo lo hemos encontrando
probando valores.
f=f(x)
err=0.5*10^(-4)
Biseccion(f,2,3,err)
Iteraciones necesarias: 15
Error cometido: 0.00003052
Aproximacion: 2.99996948242188
x=2.87673950195312
x=x*60
print 'Tiempo necesario en minutos para que la concentración se reduzca
prácticamente a 0 con un error de 4 cifras significativas: ',x
Tiempo necesario en minutos para que la concentración se reduzca
prácticamente a 0 con un error de 4 cifras significativas:
172.604370117187
Método de Newton
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 9/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
Si recordamos el método de la Bisección para encontrar la raíz de una función es necesario conocer
previamente el intervalo en el que se encuentra la raíz. Este problema se salva utilizando el método de
Newton, pues basta conocer un punto inicial x 0 en el que comenzar a determinar la sucesión de números
que convergerá a la raíz buscada. Consideremos la función
f(x) = e x − 4
f(x) = e^x - 4
plot(f(x),x,figsize=4)
Por defecto, la función plot(f(x),x) representa la función f(x) en el intervalo [0, 1]. Además, observamos
que en él, la función no tiene raices, por lo que vamos a modificar el intervalo de representación.
plot(f(x),(x,0,4),figsize=4)
Vemos que la raíz se encuentra en el intervalo [1,2], entonces vamos a considerar como valor inicial
óptimo un valor de ese intervalo, por ejemplo el punto medio. Además, para poder aplicar el método de
Newton es necesario calcular la derivada de la función f(x), utilizando la función .diff(x).
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 10/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
f(x) = e^x - 4
derf(x) = f.diff(x)
print "f(x) = ", f(x)
print "f'(x) = ", derf(x)
f(x) = e^x - 4
f'(x) = e^x
a,b = 1,2
x0 = (a+b)/2.0
print "x0 = ", x0.n(digits=4)
x0 = 1.500
Por tanto, como el método de Newton construye una sucesión numérica x n del siguiente modo:
f(x n − 1)
xn = xn − 1 − ′
f (x n − 1)
por lo que en cada iteración n, para encontrar una aproximación de la raíz (x n) solo es necesario conocer el
valor aproximado de la raíz en la iteración anterior x n − 1.
x1 = x0 - f(x0)/derf(x0)
print "Iteración 1:"
print "Aproximación de la raíz:", x1.n(digits=5)
Iteración 1:
Aproximación de la raíz: 1.3925
En el caso particular del método de Newton, el error que se comete en la iteración n será
error n = | x n − x n − 1|
es decir, será la diferencia, en valor absoluto, entre la aproximación obtenida en la iteración n y la obtenida
en la iteración n-1.
error = abs(x1-x0)
print "Error cometido en la iteración 1:", error.n(digits=5)
Error cometido en la iteración 1: 0.10748
Observamos que con 1 iteración el error que se comete es, aproximadamente, 0.11.
Ejercicio 5. Crea una función que aplique el método de Newton para encontrar una
aproximación de una raíz de una función f(x) partiendo de un valor inicial x0 y con un
error permitido err, esto es, debe recibir como argumentos la función f(x), el valor
inicial x0, y el error err, y debe devolver la aproximación de la raíz encontrada xn, así
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 11/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
como el error que se comete al encontrarla. En esta ocasión, para que se cumpla el
error utiliza while.
Inicializamos el contador a 1
Calculamos la aproximación de la raíz y el error cometido mediante las fórmulas que se indican en el
código
A continuación hacemos un bucle mientras que el error cometido sea mayor que el permitido:
Incrementamos el contador
Volvemos a realizar las fórmulas para calcular el error cometido y la aproximación de la raíz
def Newton(f,x0,err):
cont=1
f(x)=f
derf(x)=f.diff(x)
x1 = x0 - f(x0)/derf(x0)
print "Iteración ",cont,":"
print "Aproximación de la raíz:", x1.n(digits=5)
errorx = abs(x1-x0)
print "Error cometido en la iteración ",cont,":", errorx.n(digits=5)
while errorx>err:
errorcomp = abs(x1-x0)
if errorcomp<err:
return x1,errorx
cont=cont+1
x0=x1
x1=x0-f(x0)/derf(x0)
print "Iteración ",cont,":"
print "Aproximación de la raíz:", x1.n(digits=5)
errorx = abs(x1-x0)
print "Error cometido en la iteración ",cont,":",
errorx.n(digits=5)
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 12/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
ln(x 2) = 0.7
para obtener una aproximación de la raíz positiva con un error máximo permitido de
0.05. Considera el valor inicial x 0 que desees.
f(x)=ln(x^2)-0.7
plot(f(x),(x,0,4),figsize=4)
a,b = 1,2
x0 = (a+b)/2.0
print "x0 = ", x0.n(digits=4)
x0 = 1.500
f=f(x)
err=0.05
Newton(f,x0,err)
Iteración 1 :
Aproximación de la raíz: 1.4168
Error cometido en la iteración 1 : 0.083198
Iteración 2 :
Aproximación de la raíz: 1.4191
Error cometido en la iteración 2 : 0.0022634
(1.41906573968987, 0.00226340185211593)
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 13/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
f(x) = 3x 3 − 5x 2 + 2x − 4
f(x)=3*x^3-5*x^2+2*x-4
a, b = 1,2
plot(f(x),(x,a,b),figsize=4,color='blue',thickness=2)
Según el Teorema de Bolzano, si nos fijamos en la gráfica anterior observamos que cambia de signo
en el intervalo [1,2], por lo que existe una raíz en este intervalo. Este intervalo lo hemos encontrando
probando valores.
a) En primer lugar vamos a usar el método de la bisección para encontrar un aproximación positiva
de la raíz en el intervalo hallado [1,2] con un error máximo de 0.05
f=f(x)
err=0.05
Biseccion(f,1,2,err)
Iteraciones necesarias: 5
Error cometido: 0.03125
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 14/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
Aproximacion: 1.71875000000000
b) Ahora, utilizaremos el método de Newton y consideraremos el valor inicial como el punto medio
del intervalo [1,2].
a,b = 1,2
x0 = (a+b)/2.0
err=0.05
Newton(f,x0,err)
Iteración 1 :
Aproximación de la raíz: 1.7931
Error cometido en la iteración 1 : 0.29310
Iteración 2 :
Aproximación de la raíz: 1.7311
Error cometido en la iteración 2 : 0.061954
Iteración 3 :
Aproximación de la raíz: 1.7275
Error cometido en la iteración 3 : 0.0036052
(1.72754407961281, 0.00360515652062965)
Vectores y Matrices
Antes de comenzar a trabajar con Sistemas de Ecuaciones Lineales, es necesario hacer un repaso previo a
cómo construir vectores y matrices en Sage, así como las distintas operaciones que podemos realizar con
ellas.
En primer lugar, para crear vectores en Sage utilizamos la función vector() que permite considerar como
vector una lista de números. Como observamos se trata de un vector con números enteros, pero
normalmente nos interesa trabajar con valores reales, para ello, y de manera generalizada, se puede
añadir RDF como primer argumento a la función vector().
v = vector([1,2,3,4]); print v
v = vector(RDF,[1,2,3,4]); show(v)
(1, 2, 3, 4)
(1.0, 2.0, 3.0, 4.0)
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 15/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
Por otro lado, para construir matrices en Sage se emplea la función matrix(), al igual que ocurre con los
vectores si se queremos trabajar con números reales debemos situar como primer argumento el valor RDF.
Ahora bien, las matrices se crean como una lista de listas, esto es, una lista cuyos elementos serán listas
que representen los elementos de una fila.
A = matrix(RDF,[[1,2,4,3],[2,1,4,5],[3,4,1,6],[4,5,1,7]])
show(A)
( )
1.0 2.0 4.0 3.0
2.0 1.0 4.0 5.0
3.0 4.0 1.0 6.0
4.0 5.0 1.0 7.0
Por otro lado, para hacer referencia a un elemento de una matriz, se debe indicar la posición de dicho
elemento entre corchetes, de modo que el elemento de la fila 1 y columna 1 se corresponde al valor A[0,0].
A[0,0]
1.0
Para trabajar con filas o columnas enteras de una matriz se utiliza el símbolo : para indicar que se toman
todos los elementos según se sitúe [:,a] o [a,:] que indica seleccionar todos los elementos de la columna o
de la fila (respectivamente) a+1.
A[:,1] #Columna 2
[2.0]
[1.0]
[4.0]
[5.0]
A[1,:] #Fila 2
[2.0 1.0 4.0 5.0]
( )
1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 7.0
Ax = b
Si la matriz A tiene inversa (esto es, su determinante es no nulo), entonces se puede obtener el vector de
incógnitas como
x = A − 1b
Como observamos para encontrar el vector de soluciones x multiplicamos por la derecha la matriz A al
vector b, por ello en Sage puede resolverse el sistema de ecuaciones lineales utilizando la
función .solve_right().
}
x+z =1
2x + y =2
− x + y − 2z =3
A = matrix(RDF,[[1,0,1],[2,1,0],[-1,1,-2]]); show(A)
b = vector(RDF,[1,2,3]); show(b)
x = A.solve_right(b); show(x)
( )
1.0 0.0 1.0
2.0 1.0 0.0
− 1.0 1.0 − 2.0
Métodos Iterativos
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 17/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
Cuando se trata de un sistema de ecuaciones lineales de grandes dimensiones, los métodos de Gauss y
Gauss con pivoteo parcial requieren muchas operaciones y son muy sensibles a errores de redondeo, por lo
que no son muy adecuados para resolver este tipo de sistemas.
Para resolver sistemas de ecuaciones lineales con grandes dimensiones, o sistemas en los que la matriz de
coeficientes es dispersa (es decir, presenta muchos ceros), se utilizan métodos iterativos que construyen
una sucesión de vectores x 0, x 1, . . . que converjan al vector solución del sistema x.
Estos métodos se basan en el método del Punto Fijo para variables n dimesionales.
Ax = b
es fácil escribir la matriz de coeficientes A como una diferencia de dos matrices M y N, tal que
A=M−N
(M − N)x = b
o equivalentemente
Mx = Nx + b
por lo tanto,
x = M − 1(Nx + b)
Si denotamos por F(x) = M − 1(Nx + b), entonces tenemos que x = F(x), esto es, ya hemos conseguido la
función del punto fijo. Por lo tanto, todo método iterativo se construye de la forma
x = M − 1(Nx + b)
Por tanto, para un vector inicial x 0, en la iteración n se obtiene una aproximación del vector solución
x n = M − 1(Nx n − 1 + b)
2) Que la solución que se construye converja al vector solución del sistema x.
A es diagonalmente dominante, o,
A t es diagonalmente dominante, o,
A es simétrica y definida positiva,
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 18/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
entonces existe una única solución del sistema y los métodos iterativos producen una sucesión de vectores
que converge a dicha solución.
|a kk | > ∑ | a kj | , k = 1, 2, . . . , n
j=1,j≠k
A = matrix(RDF,[[2,-1,0],[1,6,-2],[4,-3,8]]); show(A)
( )
2.0 − 1.0 0.0
1.0 6.0 − 2.0
4.0 − 3.0 8.0
def is_diagonally_dominant(A):
n = A.dimensions()[0]
is_dd = True
for k in [0..(n-1)]:
s = - abs(A[k,k])
for j in [0..(n-1)]:
s = s + abs(A[k,j])
if abs(A[k,k])<=s:
is_dd = False
return is_dd
return is_dd
is_diagonally_dominant(A)
True
A.is_symmetric()
False
A.is_positive_definite()
False
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 19/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
( )
4 1 1
−2 3 1
1 1 3
Para saber si permite construir una sucesión de vectores convergente utilizando métodos iterativos,
se tiene que cumplir al menos una de las siguientes condiciones:
A = matrix(RDF,[[4,1,1],[-2,3,1],[1,1,3]])
is_diagonally_dominant(A)
False
At=matrix(RDF,[[4,-2,1],[1,3,1],[1,1,3]])
is_diagonally_dominant(At)
True
Como si lo es, podemos concluir con que la matriz A si que permite construir una sucesión de
vectores convergente utilizando métodos iterativos.
Por otro lado, una matriz A lleva asociada tres matrices D, L y U, tales que
A=D+L+U
donde
A = matrix(RDF,[[2,-1,3],[1,6,-1],[4,-1,3]]); show(A)
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 20/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
( )
2.0 − 1.0 3.0
1.0 6.0 − 1.0
4.0 − 1.0 3.0
Para construir la matriz D se utiliza la función diagonal_matrix(), mientras que para obtener las matrices L
y U empleamos las funciones creadas lower_triangular_matrix() y upper_triangular_matrix(),
respectivamente.
D = diagonal_matrix(A.diagonal()); show(D)
( )
2.0 0.0 0.0
0.0 6.0 0.0
0.0 0.0 3.0
def lower_triangular_matrix(A):
n = A.dimensions()[0]
L = matrix(RDF,n,n)
for k in [1..(n-1)]:
for j in [0..(k-1)]:
L[k,j] = A[k,j]
return L
L = lower_triangular_matrix(A); show(L)
( )
0.0 0.0 0.0
1.0 0.0 0.0
4.0 − 1.0 0.0
def upper_triangular_matrix(A):
n = A.dimensions()[0]
U = matrix(RDF,n,n)
for k in [0..(n-2)]:
for j in [(k+1)..(n-1)]:
U[k,j] = A[k,j]
return U
U = upper_triangular_matrix(A); show(U)
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 21/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
( )
0.0 − 1.0 3.0
0.0 0.0 − 1.0
0.0 0.0 0.0
M=D
N = − (L + U)
de modo que la sucesión se construye partiendo del valor inicial x 0 tal que para la iteración n es:
Dx n = − (L + U)x n − 1 + b
}
2x − y =9
x + 6y − 2z = 15
4x − 3y + 8z =1
vamos a aplicar el método de Jacobi partiendo del valor inicial x 0 = (0, 0, 0).
A:
( )
2.0 − 1.0 0.0
1.0 6.0 − 2.0
4.0 − 3.0 8.0
b:
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 22/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
( )
2.0 0.0 0.0
0.0 6.0 0.0
0.0 0.0 8.0
L:
( )
0.0 0.0 0.0
1.0 0.0 0.0
4.0 − 3.0 0.0
U:
( )
0.0 − 1.0 0.0
0.0 0.0 − 2.0
0.0 0.0 0.0
( )
2.0 0.0 0.0
0.0 6.0 0.0
0.0 0.0 8.0
N:
( )
− 0.0 1.0 − 0.0
− 1.0 − 0.0 2.0
− 4.0 3.0 − 0.0
x1 = M.solve_right(N*x0+b)
print "Aproximación del vector solución en la iteración 1:"; show(x1)
Aproximación del vector solución en la iteración 1:
(4.5, 2.5, 0.125)
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 23/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
Veamos cuál es la solución real del sistema de ecuaciones Ax = b, para comprobar cómo de precisa es la
aproximación x 1 obtenida. Se puede concluir que la aproximación de la primera incógnita es próxima al
valor real, pero no así con las otras dos incógnitas. Por ello, será necesario seguir realizando iteraciones.
A.solve_right(b)
n = 4
x0 = vector(RDF,3); print "x0:", x0
for i in [1..n]:
x1 = M.solve_right(N*x0+b)
print "Iteración ",i," :"
print "Aproximación del vector solución:"
show(x1)
x0 = x1
print
Ejercicio 9. Crea una función que reciba una matriz A, el vector de términos
independientes b, el número de iteraciones n, y un valor inicial x0, y muestre por
pantalla las soluciones del sistema Ax = b obtenidas cada una de las n iteraciones del
método de Jacobi.
def Jacobi(A,b,n,x0):
print "Iteración",i
x1 = M.solve_right(N*x0+b)
print "Solución:", x1
error = map(abs,x0-x1)
print "Errores:", error
x0 = x1
error = max(error)
i = i+1
print
M=D+L
N= −U
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 24/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
de modo que la sucesión se construye partiendo del valor inicial x 0 tal que para la iteración n es
(D + L)x n = − Ux n − 1 + b
}
2x − y =9
x + 6y − 2z = 15
4x − 3y + 8z =1
vamos a aplicar el método de Jacobi partiendo del valor inicial x 0 = (0, 0, 0).
n = 4
x0 = vector(RDF,3); print "x0:", x0
for i in [1..n]:
x1 = M.solve_right(N*x0+b)
print "Iteración ",i," :"
print "Aproximación del vector solución:"
show(x1)
x0 = x1
print
Ejercicio 10. Crea una función que reciba una matriz A, el vector de términos
independientes b, y el número de iteraciones n, y un valor inicial x0, y muestre por
pantalla las soluciones del sistema Ax = b obtenidas cada una de las n iteraciones del
método de Gauss-Seidel.
def Gauss(A,b,n,x0):
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 25/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
}
5x + y + 3t =4
3x + 7y − 2z + t = −2
2x + y + 9z − 3t =1
x + 2y + 4t =0
}
4x − y + z =7
4x − 8y + z = − 21
− 2x + y + 5z = 15
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 26/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
Los sistemas de ecuaciones lineales no son los únicos que pueden aparecer en situaciones reales, es más
son poco habituales. En general, en estas situaciones suelen aparecer sistemas de ecuaciones no lineales,
como por ejemplo:
x3 − y2
x 2 + 2y 2 − 1
=0
=0 }
Este tipo de sistemas de ecuaciones no lineal, se puede escribir como:
}
f 1(x 1, x 2, . . . , x n) =0
f 2(x 1, x 2, . . . , x n) =0
...
f n(x 1, x 2, . . . , x n) =0
Si denotamos por
( )
f 1(x 1, . . . , x n)
f 2(x 1, . . . , x n)
F(x 1, x 2, . . . , x n) =
...
f n(x 1, . . . , x n)
F(x 1, . . . , x n) = 0
Esta última notación nos lleva a pensar realmente buscar una solución del sistema de ecuaciones no
lineales es equivalente a buscar una raíz de la función F. Para ello, vamos a aplicar el método de Newton,
partiendo de un valor inicial x 0 para una iteración n:
x n = x n − 1 − J − 1(x n − 1)F(x n − 1)
donde J(x) es la matriz jacobiana de la función F(x). Equivalentemente, se tiene el siguiente sistema de
ecuaciones:
que nos permite encontrar la solución x d, sin embargo ésta no es la solución del sistema de ecuaciones no
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 27/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
xn = xn − 1 + xd
Para determinar la matriz jacobiana de una función F se puede calcular en Sage con la
función .derivative().
J = F.derivative(); show(J)
x1 = x0 + xd
print "Aproximación de la solución en la iteración 1:"; show(x1)
Recordemos que este es un método iterativo, por lo que habrá que seguir realizando iteraciones hasta
encontrar una solución próxima a la real.
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 28/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
n = 4
x0 = vector(RDF,[1,1])
F(x,y) = (x^3-y^2,x^2+2*y^2-1)
J = F.derivative()
for i in [1..n]:
print "Iteración ",i,":"
print
Jxi = J(x0[0],x0[1])
Fxi = -F(x0[0],x0[1])
xd = Jxi.solve_right(Fxi)
#print "Aproximación de la solución del sistema lineal:"
#print xd
#print
x1 = x0 + xd
print "Aproximación de la solución del sistema No lineal:"
print x1
print
x0 = x1
Ejercicio 13. Sea DNI la suma de los números de tu DNI, a la última cifra de tu DNI y
dni = DNI / 2.9 ln ( DNI ) Aplica 5 iteraciones del método de Newton, partiendo del valor
(1, 1, 1) para resolver el siguiente sistema de ecuaciones no lineales:
}
(12 + dni)x − y 3 − e z =1
− sin(x) + (10 + a)y − 2z =2
− 2x − cos(y) + 16sin(z) =3
DNI= sum([0,9.0,2,0,9,5,9,1])
a=9
dni=DNI/(2.9^ln(DNI))
dni
0.794478627984637
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 29/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
n=5
x0=vector(RDF,[1,1,1])
F(x,y,z)=((12+dni)*x-y^3-e^z-1,-sin(x)+(10+a)*y-2*z,-2*x-
cos(y)+16*sin(z)-3)
J = F.derivative()
for i in [1..n]:
print "Iteración ",i,":"
print
Jxi = J(x0[0],x0[1],x0[2])
Fxi = -F(x0[0],x0[1],x0[2])
xd = Jxi.solve_right(Fxi)
#print "Aproximación de la solución del sistema lineal:"
x1 = x0 + xd
print "Aproximación de la solución del sistema No lineal:"
print x1
print
Iteración 1 :
Iteración 2 :
Iteración 3 :
Aproximación de la solución del sistema No lineal:
(0.18117352574640072, 0.03854593080376345, 0.27609313182697315)
Iteración 4 :
Iteración 5 :
Ejercicio 14. Aplica 5 iteraciones del método de Newton, partiendo del valor (1, 1)
para resolver el siguiente sistema de ecuaciones no lineales:
xy 3 − 2y
y2 + x + y
= −1
=1 }
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 30/31
20/12/22, 21:33 GIIT_AMA_2223_Practica6_dgilpare_calvarezju -- Sage
n=5
x0=vector(RDF,[1,1])
F(x,y)=(x*y^3-2*y+1,y^2+x+y-1)
J = F.derivative()
for i in [1..n]:
print "Iteración ",i,":"
print
Jxi = J(x0[0],x0[1])
Fxi = -F(x0[0],x0[1])
xd = Jxi.solve_right(Fxi)
#print "Aproximación de la solución del sistema lineal:"
x1 = x0 + xd
print "Aproximación de la solución del sistema No lineal:"
print x1
print
x0 = x1
Iteración 1 :
Iteración 2 :
Iteración 3 :
Aproximación de la solución del sistema No lineal:
(0.21666666666666667, 0.5166666666666667)
Iteración 4 :
Iteración 5 :
https://sage-cum.unex.es:8015/home/GIT21dgilpare/13/ 31/31