You are on page 1of 6

#Methode de Jacobi

#fonction inverse
def inv_diag(D::Matrix{Float64}):

import numpy as np
from numpy.linalg import *

def jacobi(A, b, x0, tol, maxiter=200):


"""
Performs Jacobi iterations to solve the line system of
equations, Ax=b, starting from an initial guess, ``x0``.

Terminates when the change in x is less than ``tol``, or


if ``maxiter`` [default=200] iterations have been exceeded.

Returns 3 variables:
1. x, the estimated solution
2. rel_diff, the relative difference between last 2
iterations for x
3. k, the number of iterations used. If k=maxiter,
then the required tolerance was not met.
"""
n = A.shape[0]
x = x0.copy()
x_prev = x0.copy()
k = 0
rel_diff = tol * 2

while (rel_diff > tol) and (k < maxiter):

for i in range(0, n):


subs = 0.0
for j in range(0, n):
if i != j:
subs += A[i,j] * x_prev[j]

x[i] = (b[i] - subs ) / A[i,i]


k += 1

rel_diff = norm(x - x_prev) / norm(x)


print(x, rel_diff)
x_prev = x.copy()

return x, rel_diff, k

# Main code starts here


# ---------------------
GL = 1.6
d = 0.8
A = np.array([
[1.0, 0, 0, 0, 0],
[ GL, -(d+1), 1.0, 0, 0],
[ 0, d, -(d+1), 1.0, 0],
[ 0, 0, d, -(d+1), 1.0],
[ 0, 0, 0, 0, 1.0]])
b = [0.5, 0, 0, 0, 0.1]
x0 = np.zeros(5);

tol = 1E-9
maxiter = 200
x, rel_diff, k = jacobi(A, b, x0, tol, maxiter)
if k == maxiter:
print(('WARNING: the Jacobi iterations did not '
'converge within the required tolerance.'))
print(('The solution is %s; within a tolerance of %g, '
'using %d iterations.' % (x, rel_diff, k)))
print('Solution error = norm(Ax-b) = %g' % \
norm(np.dot(A,x)-b))
print('Condition number of A = %0.5f' % cond(A))
print('Solution from built-in functions = %s' % solve(A, b))

#LIANTSOA

def jacobi(A,b,Imax,eps,x0):
D=np.diag(np.diag(A))
N=D-A
r=A*x0-b
x=x0
i=0
while ((i<Imax) and ((la.norm(r))<eps)):
x=(la.inv(D))*N*x+(la.inv(D))*b
r=A*x-b
i=i+1
return x

A=np.array([[1,2,3],[4,5,6],[7,8,9]])
x0=np.array([[1],[1],[1]])
b=np.array([[3],[6],[7]])
print(jacobi(A,b,1000,10**(-3),x0))

using LinearAlgebra

function extraire_mat(A::Matrix{Float64})
E = tril(A,-1)
F = tril(A,-1)
D = diag(A)
return (E,D,F)
end

# Fonction inverse
function inv_diag(D::Matrix{Float64})
nbrows, nbcols = size(D)
inverse = Zeros(Float64,nbrows, nbrows)
for i=1:nbrows
inverse[i] = 1/D[i,i]
end
return inverse
end

#Fonction methode de Jacobi


function jacobi(A::Array{Float64}, b::Vector{Float64}, x0::Vector{Float64},
itmax::Int=100,tol::Float64=1.0e-10)

nbrows, nbcols = size(A)


# on copie la vector initial
res = deepcopy(x0)
iter = 0;
while iter < itmax
iter = iter + 1
deltax = b - A*res
for i=1:nbrows
deltax[i] = deltax[i]/A[i,i]
end
res = res + deltax
# on teste si la valeur delta est inférieure à la tolérance
if norm(deltax) <= tol
return (res, iter,false)
end
end
return (res, iter, true)
end

[1:2 4:5 7:8]


A = [1:1:2 2:1:2 -2:1:1]
# Application numérique
A = [1 2 -2;1 1 1;2 2 1]
B = [2 -1 1;2 2 2;-1 -1 2]
b = [1 1 1]
x0 = [1 2 3]

jacobi(A,b,x0)

using LinearAlgebra
using Plots

function u(x)
return -sin(2*pi*x)
end

function f(x)
return 4*pi^2*sin(2*pi*x)
end

function calcul_sol_exact(N)
x = [k/N for k in 0:N]
sol_exact = u.(x)
return x, sol_exact
end

function calcul_A(N)
d = [1 for k in 1:N-2]
D = [-2 for k in 1:N-1]
return Tridiagonal(d,D,d)
end

function calcul_f(N)
return [f(k/N) for k in 1:N-1]
end
function calcul_v(N)
A = calcul_A(N)
v = A\calcul_f(N)
v = 1/(N^2) * v
return v
end

#Pour la résolution du système tridiagonal, on pourrait aussi utiliser l'algorithme


de Thomas.
#Ce devrait être plus efficace que l'utilisation de la méthode A\.
function calcul_v_Thomas(N)
a = [1. for k in 1:N-2]
b = [-2. for k in 1:N-1]
c = [1. for k in 1:N-2]
d = calcul_f(N)
x = [0. for k in 1:N-1]
for i in 2:N-1
w = a[i-1]/b[i-1]
b[i] = b[i] - w*c[i-1]
d[i] = d[i] - w*d[i-1]
end
x[N-1] = d[N-1]/b[N-1]
for i in N-2:-1:1
x[i] = (d[i] - c[i]*x[i+1])/b[i]
end
x = 1/(N^2) * x
return x
end

function calcul_erreur_approx(N)
v = vcat([0],calcul_v_Thomas(N),[0])
x, sol_exact = calcul_sol_exact(N)
erreur_approx = max(abs.(v-sol_exact)...)
return erreur_approx
end

#On trace les valeurs de u(x_k) et des solutions approchées v_k pour N=10.
#On peut rajouter l'argument seriestype = :scatter dans la fonction plot pour
n'afficher que les points.
N = 10;
x, sol_exact = calcul_sol_exact(N);
v = vcat([0],calcul_v_Thomas(N),[0]);
p = plot(x, sol_exact, label = "Solution exacte", ylabel = "y", xlabel = "x",
color=:red, title = "N = 10")
plot!(p, x, v, color=:green, label="Solution approchée")

#Même chose pour N=100.


N = 100;
x, sol_exact = calcul_sol_exact(N);
v = vcat([0],calcul_v_Thomas(N),[0]);
p = plot(x, sol_exact, label = "Solution exacte", ylabel = "y", xlabel = "x",
color=:red, title = "N = 100")
plot!(p, x, v, color=:green, label="Solution approchée")

#On trace la valeur de erreur_approx pour N allant de 3 à 100.


y = [calcul_erreur_approx(N) for N in 3:100];
plot(3:100, y, title = "Erreur en fonction de N")
#Le graphique ci-dessous permet de constater que la diminution de l'erreur est
inversement quadratique en fonction de N.
z = [1/sqrt(t) for t in y];
plot(3:100, z)

#=
Anne-CAtherine Letournel
09/03/2021
TP1 Calcul scientifique: méthode de Newton
=#

# fonction Newton, exercice 1

# calcul d'une solution particulière par la méthode de Newton


function Newton(x0, f, df, tol, itmax)
N = 1
x1 = x0
x2 = x1 - f(x1)/df(x1)
while ( abs(x2-x1) > tol && N <= itmax )
x1 = x2
x2 = x1 - f(x1)/df(x1)
N = N+1
end
return(x2,N)
end

# script de test
# initialisation des variables d'entrée
x0 = -2.5
f = x -> x^3 -4*x + 1
df = x -> 3*x^2 - 4
tol = 1e-6
itmax = 100

# appel de la fonction et affichage des résultats


y, N = Newton(x0, f, df, tol, itmax)
println("f(",y,") = ", f(y), " trouvé en ", N, " itérations.")

x0 = 0.0

# appel de la fonction et affichage des résultats


y, N = Newton(x0, f, df, tol, itmax)
println("f(",y,") = ", f(y), " trouvé en ", N, " itérations.")

x0 = 2.0

# appel de la fonction et affichage des résultats


y, N = Newton(x0, f, df, tol, itmax)
println("f(",y,") = ", f(y), " trouvé en ", N, " itérations.")

# cas particulier d'un polynome de degré 3


function NewtonPoly(x0 ,a, b, c, d, tol, itmax)
N = 1
x1 = x0
x2 = x1 - (a*x1^3 + b*x1^2 + c*x1 + d) / (3*a*x1^2 + 2*b*x1 + c)
while ( abs(x2-x1) > tol && N <= itmax )
x1 = x2
x2 = x1 - (a*x1^3 + b*x1^2 + c*x1 + d) / (3*a*x1^2 + 2*b*x1 + c)
N = N+1
end
return(x2, N)
end

# script de test
# initialisation des variables d'entrée
x0 = -2.5
a = 1
b = 0
c = -4
d = 1
tol = 1e-6
itmax = 100

# appel de la fonction et affichage des résultats


x1, N = Newton(x0, f, df, tol, itmax)
println("f(",x1,") = ", f(x1), " trouvé en ", N, " itérations.")

You might also like