Sei sulla pagina 1di 23

# -*- coding: utf-8 -*-

"""
Created on Mon May 17 05:51:56 2021

@author: damia
"""
import numpy as np

def TrapComp(fname,a,b,n):
h=(b-a)/n
nodi=np.arange(a,b+h,h)
f=fname(nodi)
I=(f[0]+2*np.sum(f[1:n])+f[n])*h/2
return I

def SimpComp(fname,a,b,n):
h=(b-a)/(2*n)
nodi=np.arange(a,b+h,h)
f=fname(nodi)
I=(f[0]+2*np.sum(f[2:2*n:2])+4*np.sum(f[1:2*n:2])+f[2*n])*h/3
return I

def traptoll(fun,a,b,tol):

Nmax=2048
err=1

N=1;
IN=TrapComp(fun,a,b,N);

while N<=Nmax and err>tol :


N=2*N
I2N=TrapComp(fun,a,b,N)
err=abs(IN-I2N)/3
IN=I2N

if N>Nmax:
print('Raggiunto nmax di intervalli con traptoll')
N=0
IN=[]

return IN,N

def simptoll(fun,a,b,tol):

Nmax=2048
err=1

N=1;
IN=SimpComp(fun,a,b,N);

while N<=Nmax and err>tol :


N=2*N
I2N=SimpComp(fun,a,b,N)
err=abs(IN-I2N)/15
IN=I2N

if N>Nmax:
print('Raggiunto nmax di intervalli con traptoll')
N=0
IN=[]
return IN,N
# -*- coding: utf-8 -*-
"""
Created on Sat May 1 14:12:39 2021

@author: damia
"""
import numpy as np
def plagr(xnodi,k):
"""
Restituisce i coefficienti del k-esimo pol di
Lagrange associato ai punti del vettore xnodi
"""
xzeri=np.zeros_like(xnodi)
n=xnodi.size
if k==0:
xzeri=xnodi[1:n]
else:
xzeri=np.append(xnodi[0:k],xnodi[k+1:n])

num=np.poly(xzeri)
den=np.polyval(num,xnodi[k])

p=num/den

return p

def InterpL(x, f, xx):


""""
%funzione che determina in un insieme di punti il valore del polinomio
%interpolante ottenuto dalla formula di Lagrange.
% DATI INPUT
% x vettore con i nodi dell'interpolazione
% f vettore con i valori dei nodi
% xx vettore con i punti in cui si vuole calcolare il polinomio
% DATI OUTPUT
% y vettore contenente i valori assunti dal polinomio interpolante
%
"""
n=x.size
m=xx.size
L=np.zeros((n,m))
for k in range(n):
p=plagr(x,k)
L[k,:]=np.polyval(p,xx)

return np.dot(f,L)
# -*- coding: utf-8 -*-
"""
File per la soluzione di sistemi Lineari
"""
import numpy as np

def Lsolve(L,b):
"""
Risoluzione con procedura forward di Lx=b con L triangolare inferiore
Input: L matrice triangolare inferiore
b termine noto
Output: x: soluzione del sistema lineare
flag= 0, se sono soddisfatti i test di applicabilità
1, se non sono soddisfatti
"""
#test dimensione
m,n=L.shape
flag=0;
if n != m:
print('errore: matrice non quadrata')
flag=1
x=[]
return x, flag

# Test singolarita'
if np.all(np.diag(L)) != True:
print('el. diag. nullo - matrice triangolare inferiore')
x=[]
flag=1
return x, flag
# Preallocazione vettore soluzione
x=np.zeros((n,1))

for i in range(n):
s=np.dot(L[i,:i],x[:i]) #scalare=vettore riga * vettore colonna
x[i]=(b[i]-s)/L[i,i]

return x,flag

def Usolve(U,b):

"""
Risoluzione con procedura backward di Rx=b con R triangolare superiore
Input: U matrice triangolare superiore
b termine noto
Output: x: soluzione del sistema lineare
flag= 0, se sono soddisfatti i test di applicabilità
1, se non sono soddisfatti

"""
#test dimensione
m,n=U.shape
flag=0;
if n != m:
print('errore: matrice non quadrata')
flag=1
x=[]
return x, flag

# Test singolarita'
if np.all(np.diag(U)) != True:
print('el. diag. nullo - matrice triangolare superiore')
x=[]
flag=1
return x, flag
# Preallocazione vettore soluzione
x=np.zeros((n,1))

for i in range(n-1,-1,-1):
s=np.dot(U[i,i+1:n],x[i+1:n]) #scalare=vettore riga * vettore colonna
x[i]=(b[i]-s)/U[i,i]

return x,flag

def LUsolve(L,U,P,b):
"""
Risoluzione a partire da PA =LU assegnata
"""
Pb=np.dot(P,b)
y,flag=Lsolve(L,Pb)
if flag == 0:
x,flag=Usolve(U,y)
else:
return [],flag

return x,flag

def LU_nopivot(A):
"""
% Fattorizzazione PA=LU senza pivot versione vettorizzata
In output:
L matrice triangolare inferiore
U matrice triangolare superiore
P matrice identità
tali che LU=PA=A
"""
# Test dimensione
m,n=A.shape

flag=0;
if n!=m:
print("Matrice non quadrata")
L,U,P,flag=[],[],[],1
return P,L,U,flag

P=np.eye(n);
U=A.copy();
# Fattorizzazione
for k in range(n-1):
#Test pivot
if U[k,k]==0:
print('elemento diagonale nullo')
L,U,P,flag=[],[],[],1
return P,L,U,flag

# Eliminazione gaussiana
U[k+1:n,k]=U[k+1:n,k]/U[k,k] # Memorizza i moltiplicatori
U[k+1:n,k+1:n]=U[k+1:n,k+1:n]-np.outer(U[k+1:n,k],U[k,k+1:n]) # Eliminazione gaussiana sulla matrice

L=np.tril(U,-1)+np.eye(n) # Estrae i moltiplicatori


U=np.triu(U) # Estrae la parte triangolare superiore + diagonale
return P,L,U,flag

def LU_nopivotv(A):
"""
% Fattorizzazione PA=LU senza pivot versione vettorizzata intermedia
In output:
L matrice triangolare inferiore
U matrice triangolare superiore
P matrice identità
tali che LU=PA=A
"""
# Test dimensione
m,n=A.shape

flag=0;
if n!=m:
print("Matrice non quadrata")
L,U,P,flag=[],[],[],1
return P,L,U,flag

P=np.eye(n);
U=A.copy();
# Fattorizzazione
for k in range(n-1):
#Test pivot
if U[k,k]==0:
print('elemento diagonale nullo')
L,U,P,flag=[],[],[],1
return P,L,U,flag

# Eliminazione gaussiana
for i in range(k+1,n):
U[i,k]=U[i,k]/U[k,k] # Memorizza i moltiplicatori
U[i,k+1:n]=U[i,k+1:n]-U[i,k]*U[k,k+1:n] # Eliminazione gaussiana sulla matrice

L=np.tril(U,-1)+np.eye(n) # Estrae i moltiplicatori


U=np.triu(U) # Estrae la parte triangolare superiore + diagonale
return P,L,U,flag

def LU_nopivotb(A):
"""
% Fattorizzazione PA=LU senza pivot versione base
In output:
L matrice triangolare inferiore
U matrice triangolare superiore
P matrice identità
tali che LU=PA=A
"""
# Test dimensione
m,n=A.shape
flag=0;
if n!=m:
print("Matrice non quadrata")
L,U,P,flag=[],[],[],1
return P,L,U,flag

P=np.eye(n);
U=A.copy();
# Fattorizzazione
for k in range(n-1):
#Test pivot
if U[k,k]==0:
print('elemento diagonale nullo')
L,U,P,flag=[],[],[],1
return P,L,U,flag

# Eliminazione gaussiana
for i in range(k+1,n):
U[i,k]=U[i,k]/U[k,k]
for j in range(k+1,n): # Memorizza i moltiplicatori
U[i,j]=U[i,j]-U[i,k]*U[k,j] # Eliminazione gaussiana sulla matrice

L=np.tril(U,-1)+np.eye(n) # Estrae i moltiplicatori


U=np.triu(U) # Estrae la parte triangolare superiore + diagonale
return P,L,U,flag

def swapRows(A,k,p):
A[[k,p],:] = A[[p,k],:]

def LU_pivot(A):
"""
% Fattorizzazione PA=LU con pivot
In output:
L matrice triangolare inferiore
U matrice triangolare superiore
P matrice di permutazione
tali che PA=LU
"""
# Test dimensione
m,n=A.shape
flag=0;
if n!=m:
print("Matrice non quadrata")
L,U,P,flag=[],[],[],1
return P,L,U,flag

P=np.eye(n);
U=A.copy();
# Fattorizzazione
for k in range(n-1):
#Scambio di righe nella matrice U e corrispondente scambio nella matrice di permutazione per
# tenere traccia degli scambi avvenuti

#Fissata la colonna k-esima calcolo l'indice di riga p a cui appartiene l'elemento di modulo massimo a partire dalla riga k-
esima
p = np.argmax(abs(U[k:n,k])) + k
if p != k:
swapRows(P,k,p)
swapRows(U,k,p)

# Eliminazione gaussiana
U[k+1:n,k]=U[k+1:n,k]/U[k,k] # Memorizza i moltiplicatori
U[k+1:n,k+1:n]=U[k+1:n,k+1:n]-np.outer(U[k+1:n,k],U[k,k+1:n]) # Eliminazione gaussiana sulla matrice

L=np.tril(U,-1)+np.eye(n) # Estrae i moltiplicatori


U=np.triu(U) # Estrae la parte triangolare superiore + diagonale
return P,L,U,flag

def solve_nsis(A,B):
# Test dimensione
m,n=A.shape
flag=0;
if n!=m:
print("Matrice non quadrata")

return

Y= np.zeros((n,n))
X= np.zeros((n,n))
P,L,U,flag= LU_nopivot(A)
if flag==0:
for i in range(n):
y,flag=Lsolve(L,np.dot(P,B[:,i]))
Y[:,i]=y.squeeze(1)
x,flag= Usolve(U,Y[:,i])
X[:,i]=x.squeeze(1)
else:
print("Elemento diagonale nullo")
X=[]
return X
"""
Funzioni per il calcolo degli zeri di funzioni non lineari
"""
import numpy as np
import math

'''
Il core Python non possiede la funzione sign.
La funzione copysign(a,b) del modulo math restituisce un valore numerico che ha il valore assoluto di
a e segno di b.
Per avere il segno di un valore numerico b si può usare math.copysign(1,b)
che resistuisce 1 se b>0, -1 se b<0, 0 se b è zero
'''

def sign(x): return math.copysign(1, x)

#Bisezione
def bisez(fname,a,b,tol):
eps=np.spacing(1) # np.spacing(x) Restituisce la distanza tra x e il numero adiacente più vicino.
# np.spacing(1) restituisce quindi l' eps di macchina.
fa=fname(a)
fb=fname(b)
if sign(fa)==sign(fb):
print('intervallo non corretto --Metodo non applicabile')
return [],0,[]
else:
maxit=int(math.ceil(math.log((b-a)/tol)/math.log(2)))
print('n. di passi necessari=',maxit,'\n');
xk=[]
it=0
#while it<maxit and abs(b-a)>=tol+eps*max(abs(a),abs(b)):
while it<maxit and abs(b-a)>=tol:
c=a+(b-a)*0.5 #formula stabile per il calcolo del punto medio dell'intervallo
xk.append(c)
it+=1
if c==a or c==b:
break
fxk=fname(c)
if fxk==0:
break
elif sign(fxk)==sign(fa):
a=c
fa=fxk
elif sign(fxk)==sign(fb):
b=c
fb=fxk

x=c

return x,it,xk

def regula_falsi(fname,a,b,tol,nmax):
#Regula Falsi
eps=np.spacing(1)
xk=[]
fa=fname(a)
fb=fname(b)
if sign(fa)==sign(fb):
print('intervallo non corretto --Metodo non applicabile')
return [],0,[]
else:
it=0
fxk=fname(a)
while it<nmax and abs(b-a)>=tol+eps*max(abs(a),abs(b)) and abs(fxk)>=tol :
x1=a-fa*(b-a)/(fb-fa);
xk.append(x1)
it+=1
fxk=fname(x1);
if fxk==0:
break
elif sign(fxk)==sign(fa):
a=x1;
fa=fxk;
elif sign(fxk)==sign(fb):
b=x1;
fb=fxk;

if it==nmax :
print('Regula Falsi: Raggiunto numero max di iterazioni')

return x1,it,xk

def corde(fname,fpname,x0,tolx,tolf,nmax):
#Corde
xk=[]
m=fpname(x0) #m= Coefficiente angolare della tangente in x0
fx0=fname(x0)
d=fx0/m
x1=x0-d
fx1=fname(x1)
xk.append(x1)
it=1
while it<nmax and abs(fx1)>=tolf and abs(d)>=tolx*abs(x1) :
x0=x1
fx0=fname(x0)
d=fx0/m
'''
#x1= ascissa del punto di intersezione tra la retta che passa per il punto
(xi,f(xi)) e ha pendenza uguale a m e l'asse x
'''
x1=x0-d
fx1=fname(x1)
it=it+1
xk.append(x1)

if it==nmax:
print('raggiunto massimo numero di iterazioni \n')

return x1,it,xk

#Secanti
def secanti(fname,xm1,x0,tolx,tolf,nmax):
xk=[]
fxm1=fname(xm1);
fx0=fname(x0);
d=fx0*(x0-xm1)/(fx0-fxm1)
x1=x0-d;
xk.append(x1)
fx1=fname(x1);
it=1
while it<nmax and abs(fx1)>=tolf and abs(d)>=tolx*abs(x1):
xm1=x0
x0=x1
fxm1=fname(xm1)
fx0=fname(x0)
d=fx0*(x0-xm1)/(fx0-fxm1)
x1=x0-d
fx1=fname(x1)
xk.append(x1);
it=it+1;

if it==nmax:
print('Secanti: raggiunto massimo numero di iterazioni \n')

return x1,it,xk

def newton(fname,fpname,x0,tolx,tolf,nmax):
#Newton
xk=[]
fx0=fname(x0)
dfx0=fpname(x0)
if abs(dfx0)>np.spacing(1):
d=fx0/dfx0
x1=x0-d
fx1=fname(x1)
xk.append(x1)
it=0

else:
print('Newton: Derivata nulla in x0 - EXIT \n')
return [],0,[]

it=1
while it<nmax and abs(fx1)>=tolf and abs(d)>=tolx*abs(x1):
x0=x1
fx0=fname(x0)
dfx0=fpname(x0)
if abs(dfx0)>np.spacing(1):
d=fx0/dfx0
x1=x0-d
fx1=fname(x1)
xk.append(x1)
it=it+1
else:
print('Newton: Derivata nulla in x0 - EXIT \n')
return x1,it,xk

if it==nmax:
print('Newton: raggiunto massimo numero di iterazioni \n');

return x1,it,xk

def stima_ordine(xk,iterazioni):
p=[]

for k in range(iterazioni-3):
p.append(np.log(abs(xk[k+2]-xk[k+3])/abs(xk[k+1]-xk[k+2]))/np.log(abs(xk[k+1]-xk[k+2])/abs(xk[k]-xk[k+1])));

ordine=p[-1]
return ordine

#Newton Modificato
def newton_m(fname,fpname,x0,m,tolx,tolf,nmax):
eps=np.spacing(1)
xk=[]
#xk.append(x0)
fx0=fname(x0)
dfx0=fpname(x0)
if abs(dfx0)>eps:
d=fx0/dfx0
x1=x0-m*d
fx1=fname(x1)
xk.append(x1)
it=0

else:
print('Newton: Derivata nulla in x0 \n')
return [],0,[]

it=1
while it<nmax and abs(fx1)>=tolf and abs(d)>=tolx*abs(x1):
x0=x1
fx0=fname(x0)
dfx0=fpname(x0)
if abs(dfx0)>eps:
d=fx0/dfx0
x1=x0-m*d
fx1=fname(x1)
xk.append(x1)
it=it+1
else:
print('Newton Mod: Derivata nulla \n')
return x1,it,xk

if it==nmax:
print('Newton Mod: raggiunto massimo numero di iterazioni \n');

return x1,it,xk

def iterazione(gname,x0,tolx,nmax):

xk=[]
xk.append(x0)
x1=gname(x0)
d=x1-x0
xk.append(x1)
it=1
while it<nmax and abs(d)>=tolx*abs(x1) :
x0=x1
x1=gname(x0)
d=x1-x0
it=it+1
xk.append(x1)

if it==nmax:
print('Raggiunto numero max di iterazioni \n')

return x1, it,xk


# -*- coding: utf-8 -*-
"""
Created on Sat May 22 11:34:05 2021

@author: damia
"""

import numpy as np
import matplotlib.pyplot as plt
from Funzioni_Integrazione import traptoll

#Estremi di integrazione

a=0
b=1

I=[]

for n in range(1,31):
f= lambda x: x**n/(x+10)

#Stima del numero N si sottointervalli per approssimare l'integrale della


# funzione integranda con precisione tol
tol=1e-6
I1t,N1=traptoll(f,a,b,tol)
I.append(I1t)

#plt.plot(I,'r-o')
#plt.show()

nval=30
y=np.zeros((n,),dtype=float)
y[0]=np.log(11)-np.log(10)
for n in range(1,nval):
y[n]=1/n-10*y[n-1]

err_rel_y=np.abs(y-I)/np.abs(I)

z=np.zeros((nval+1,),dtype=float)
z[nval]=0.0
for n in range(nval,0,-1):
z[n-1]=1/10*(1/n-z[n])

err_rel_z=np.abs(z[0:nval]-I)/np.abs(I)
plt.semilogy(np.arange(nval),err_rel_y,'g-.',np.arange(nval),err_rel_z,'b--')
plt.legend(['Errore relativo algoritmo b ', 'Errore relativo algoritmo c'])
plt.show()

#L'algoritmo piu' stabile e' l'algoritmo c)


# -*- coding: utf-8 -*-
"""
Created on Sat May 22 11:34:05 2021

@author: damia
"""

import numpy as np
import matplotlib.pyplot as plt
from funzioni_Interpolazione_Polinomiale import InterpL, plagr
from Funzioni_Integrazione import simptoll

f = lambda x: x-np.sqrt(x-1)

#La funzione fpol è la funzione che valuta il polinomio interpolatore


# in un numpy array val

def fpol(val):
pol=InterpL(x,y,val)
return pol

#Estremi di integrazione

a= 1
b=3
n=3

#Costruzione del polinomio di interpolazione di Lagrange di grado n=3


x=np.linspace(a,b,n+1)
y=f(x)
#Costruzione del numpy array z in cui valutare il polinomio interpolatore di Lagrange
z=np.linspace(a,b,100)
pol=InterpL(x,y,z)

#Grafico del polinomio interpolatore di Lagraznge nei punti dell'array z


plt.plot(z,f(z),z,pol,x,y,'o')
plt.legend(['Funzione da interpolare','Polinomio interpolatore', 'Nodi di interpolazione'])
plt.show()

#Stima del numero N si sottointervalli per approssimare l'integrale della


# funzione integranda con precisione tol
tol=1e-5
I1t,N1=simptoll(f,a,b,tol)

#Stima del numero N si sottointervalli per approssimare l'integrale del


# polinomio interpolatore di grado 3 con precisione tol
I2t,N2=simptoll(fpol,a,b,tol)

#I1 ed I2 sono i valori esatti dei due integrali


I1 = 2.114381916835873
I2 = 2.168048769926493

err1=abs(I1t-I1)
err2=abs(I2t-I2)

print('Errore integrale funzione f(x)', err1,' Numero di suddivisioni ', N1)


print('Errore integrale del polinomio interpolatore', err2, 'Numero di suddivisioni ',N2)

'''
Il numero di suddivisioni per il calcolo dell'integrale del polinomio interpolatore di grado
3 è uguale a 2 e l'errore commesso è dell'ordine di 1e-14, perchè l'errore
della formula di integrazione di Simpson dipende dalla derivata quarta della funzione integranda,
e poichè nel calcolo del secondo integrale, la funzione integranda è un polinomio di grado 3 che ha derivata
quarta nulla, non è necessario suddividere ancora l'intervallo di integrazione per ottenere
l'approssimazione dell'integrale con la precisione richiesta.
'''
# -*- coding: utf-8 -*-
"""
ese2
"""

import numpy as np
from funzioni_Interpolazione_Polinomiale import InterpL,plagr
import matplotlib.pyplot as plt
import math

def zeri_Cheb(n):
x=np.zeros((n+1,))
for k in range(n+1):
x[k]=np.cos(((2*k+1)/(2*(n+1))*math.pi))

return x

f= lambda x: 1/(1+900*x**2)

#a e b estremi della funzione f


a=-1
b=1;
#vettore con i punti in cui si applica il polinomio interpolante
xx=np.linspace(a,b,200);
fig=1
Le=np.zeros((200,1));
#n = 5:5:30
for n in range(5,35,5):
#vettore con i nodi dell'interpolazione
xe=np.linspace(a,b,n+1)
#vettore con i valori dei nodi dell'interpolazione
ye=f(xe)
print(xe)
print(ye)
#polinomio di interpolazione
pole=InterpL(xe,ye,xx);
re=np.abs(f(xx)-pole)

#il metodo subplot_adjust serve per spaziare meglio visivamente i grafici della tabella
plt.subplots_adjust(hspace=0.5,wspace=0.5)
plt.subplot(3,2,fig)

plt.plot(xx,np.abs(f(xx)-pole))
plt.legend(['Equidistanti n='+str(n)])
plt.subplot(3,2,fig)

fig+=1
plt.show()

fig=1
for n in range(5,35,5):
#troviamo i nodi di chebyshev tramite questa funzione
xc=zeri_Cheb(n)

yc=f(xc)
polc=InterpL(xc,yc,xx);
rc=np.abs(f(xx)-polc)
plt.subplots_adjust(hspace=0.5,wspace=0.5)
plt.subplot(3,2,fig)

plt.plot(xx,rc)
plt.legend(['Cheb'+str(n)])
fig+=1
#plt.show()

#Calcolo delle costanti di Lebesgue per ogni n


LLe=np.zeros((6,1));
LLc=np.zeros((6,1));
Lc=np.zeros((200,1))
Le=np.zeros((200,1))

i=0;
for n in range(5,35,5):
#nodi equispaziati
xe=np.linspace(a,b,n+1)
#nodi di Chebyshev
xc=zeri_Cheb(n)

Le=np.zeros((200,1));
Lc=np.zeros((200,1));
for l in range (n+1):
pe=plagr(xe,l);
Le=Le+np.abs(np.polyval(pe,xx))
pc=plagr(xc,l)
Lc=Lc+np.abs(np.polyval(pc,xx))

LLe[i]=np.max(Le)
LLc[i]=np.max(Lc)
i=i+1

plt.semilogy(range(5,35,5),LLe,range(5,35,5),LLc)
plt.legend(['Caso nodi equisistanti','Caso zeri di Chebichev'])
plt.title('Costanti di lebesgue:')
plt.show()
# -*- coding: utf-8 -*-
"""
Created on Sat May 22 11:34:05 2021

@author: damia
"""

import numpy as np
import matplotlib.pyplot as plt
import numpy.linalg as npl
from funzioni_Sistemi_lineari import LU_nopivot

A =np.array([ [10, -4, 4, 0], [-4, 10, 0, 2], [4, 0, 10, 2], [0, 2, 2, 0]],dtype=float)
B=np.array([[5, -2, 2, 0], [-2, 5, 0, 1], [2, 0, 5, 1], [0, 1, 1, 5]],dtype=float)

#Le matrici A e B ammettono fattorizzazione LU senza pivoting parziale a perno massimo?


#Verifico le ipotesi del teorema che garantisce che una matrice A ammetta fattorizzazione LU di gauss
#No pivoting, cioè che i minori principali abbiano rango massimo ((determinante diverso da zero))

det_minoreA=[]
for i in range (0,4):
det_minoreA.append(npl.det(A[:i+1,:i+1]))

if np.all(det_minoreA!=0):
print("La matrice A ammette fattorizzazione LU no-pivoting")

det_minoreB=[]
for i in range (0,4):
det_minoreB.append(npl.det(B[:i+1,:i+1]))

if np.all(det_minoreB!=0):
print("La matrice B ammette fattorizzazione LU no-pivoting")

P,L,U,flag= LU_nopivot(A)

'''
Il determinante della matrice è uguale al prodotto degli elementi diagonali della matrice U
'''

detA=np.prod(np.diag(U))
print("Determinante della matrice A ",detA)

'''
Il determinante dell'inversa di una matrice è uguale al reciproco del
determinante della matrice di partenza
'''

detinvA=1/detA
print("Determinante dell'inversa di A ",detinvA)

P,L,U,flag= LU_nopivot(B)
detB=np.prod(np.diag(U))
print("Determinante della matrice A ",detB)
detinvB=1/detB
print("Determinante dell'inversa di B ",detinvB)
# -*- coding: utf-8 -*-
"""
Esercizio 2 del 15 Gennaio
"""
import numpy as np
from funzioni_Sistemi_lineari import Lsolve, Usolve, LUsolve, LU_nopivot
from scipy.linalg import pascal

def LULUsolve(L,U,c):
#Soluzione del sistema lineare A**2 x= c che equivale a L U L U x =c
y3,flag=Lsolve(L,c)
y2,flag=Usolve(U,y3)
y1,flag=Lsolve(L,y2)
x,flag=Usolve(U,y1)
return x

for n in range(5,11):

#MAtrice di Pascal di ordine n, definita mediante la funzione pascal nel modulo scipy.linalg
A=pascal(n)
#Costruzione del termine noto del primo sistema lineare
b=np.dot(A.T,np.ones((n,1)))
#Costruzione del termine noto del secondo sistema lineare
c=np.dot(np.dot(A,A),np.ones((n,1)))
#Fattorizzazione senza strategia del pivoting della matrice A
P,L,U,flag=LU_nopivot(A)

"""
LU * x = b
L*y=b
U*x=y
"""

y, flag = Lsolve(L, np.dot(P, b))


x, flag = Usolve(U, y)

#Soluzione del sistema A.T x =b, (che equivake a U.T L.T x = b )


x1,flag=LUsolve(U.T,L.T,P,b)
print('Soluzione sistema 1 \n ',x1)
#Soluzione del sistema A**2 x=c, (che equivake a L U L U x= c)
x2=LULUsolve(L,U,c)
print('Soluzione sistema 2 \n', x2)

'''
Conviene utilizzare la strategia proposta per la soluzione del sistema 2, perchè se la matrice A
è mal condizionata, il sistema lineare con matrice A**2 ha un indice di condizionamento dell'ordine del suo
quadrato, quindi conviene risolvere i 4 sistemi lineari con matrici triangolari che hanno indice di
condizionamento sicuramente minore di A**2
'''
# -*- coding: utf-8 -*-
"""
Created on Sat May 1 11:23:27 2021

@author: damia
"""
import numpy as np
import matplotlib.pyplot as plt
import scipy.linalg as spl

#Funzioni necessarie
def Usolve(U,b):

"""
Risoluzione con procedura backward di Rx=b con R triangolare superiore
Input: U matrice triangolare superiore
b termine noto
Output: x: soluzione del sistema lineare
flag= 0, se sono soddisfatti i test di applicabilitĂ
1, se non sono soddisfatti

"""
#test dimensione
m,n=U.shape
flag=0;
if n != m:
print('errore: matrice non quadrata')
flag=1
x=[]
return x, flag

# Test singolarita'
if np.all(np.diag(U)) != True:
print('el. diag. nullo - matrice triangolare superiore')
x=[]
flag=1
return x, flag
# Preallocazione vettore soluzione
x=np.zeros((n,1))

for i in range(n-1,-1,-1):
s=np.dot(U[i,i+1:n],x[i+1:n]) #scalare=vettore riga * vettore colonna
x[i]=(b[i]-s)/U[i,i]

return x,flag

def metodoQR(x,y,n):
"""
INPUT
x vettore colonna con le ascisse dei punti
y vettore colonna con le ordinate dei punti
n grado del polinomio approssimante
OUTPUT
a vettore colonna contenente i coefficienti incogniti
"""

H=np.vander(x,n+1)
Q,R=spl.qr(H)
y1=np.dot(Q.T,y)
a,flag=Usolve(R[0:n+1,:],y1[0:n+1])
return a
#------------------------------------------------------
#Script
#----------------------------------------------------
m=12

x=np.linspace(1900,2010,12)
y=np.array([76.0,92.0,106.0,123.0,132.0,151.0,179.0,203.0,226.0,249.0,281.0,305.0])

xmin=np.min(x)
xmax=np.max(x)
xval=np.linspace(xmin,xmax,100)

for n in range(1,4):
a=metodoQR(x,y,n)
residuo=np.linalg.norm(y-np.polyval(a,x))**2
print("Norma del residuo al quadrato",residuo)
p=np.polyval(a,xval)
plt.plot(xval,p)

plt.legend(['n=1','n=2','n=3'])

plt.plot(x,y,'o')
# -*- coding: utf-8 -*-
"""
Created on Mon May 24 19:09:59 2021

@author: damia
"""

import numpy as np
import matplotlib.pyplot as plt
from funzioni_zeri import iterazione
import sympy as sym
from sympy.utilities.lambdify import lambdify

n=35
u1=np.zeros((n,),dtype=float)
u2=np.zeros((n,),dtype=float)
u3=np.zeros((n,),dtype=float)

for i in range(1,n+1):
u1[i-1]=15*((3/5)**(i)+1)/(5*(3/5)**(i)+3)

u2[0]=4
for i in range(1,n):
u2[i]=8-15/u2[i-1]
#Gli u2 e gli u1 coincidono e convergono entrambi a 5

u3[0]=4
u3[1]=17/4
for i in range(3,n+1):
u3[i-1]=108-815/u3[i-2]+1500/(u3[i-2]*u3[i-3])
print(u3)
plt.plot(range(n),u2)
plt.title('Formula 2')
#plt.show()

plt.plot(range(n),u3)
plt.title('Formula 3')
plt.show()

err_rel2=np.abs(u2-u1)/np.abs(u1)

err_rel3=np.abs(u3-u1)/np.abs(u1)

#Scala semilogaritmica
plt.semilogy(range(n),err_rel2,range(n),err_rel3)
plt.legend(['Errore relativo formula 2', 'Errore relativo formula 3'])
plt.show()

x = sym.symbols('x')
g1n = 8-15/x
g1 = lambdify(x, g1n, np)
g2 = lambdify(x, 108-815/x+ 1500/(x**2), np)

#Definisco funzione g1
dg1x=sym.diff(g1n,x,1)
dg1=lambdify(x,dg1x,np)

#Definisco funzione g2
g2x=108-815/x+1500/(x**2)
dg2x=sym.diff(g2x,x,1)
dg2=lambdify(x,dg2x,np)
g2=lambdify(x,g2x,np)

x=np.linspace(4,10,100)
plt.plot(x,g1(x))
plt.plot(x,x)
plt.legend(['g1(x)','y=x'])
plt.show()

#La g2 interseca la bisettrice in 2 punti, ha due punti fissi (x=5 ed 100) , ma la derivata prima della g2
# non soddisfa le ipotesi del teorema di convergenza locale in un intorno del primo punto fisso,5
# potrebbe essere per l'asintoto
x = np.linspace(4, 100, 100)
plt.plot(x,g2(x))
plt.plot(x,x)
plt.legend(['g2(x)','y=x'])
plt.show()

tolx=1e-5
nmax=100
x0=4
x1,xk,it=iterazione(g1,x0,tolx,nmax)
x2,xk2,it2=iterazione(g2,x0,tolx,nmax)
print("Punto fisso della funzione g1 --> ",x1)
print("Punto fisso della funzione g2 --> ",x2)

#Visualizziamo la derivata prima di g1 in un intorno di 5, sono soddisfatte le iptesi del teorema di convergenza
#locale
xx=np.linspace(2,6,100)
plt.semilogy(xx,dg1(xx))
plt.plot([2,6],[1,1])
plt.plot([2,6],[-1,-1])
plt.legend(['derivata prima di g1 in un intorno di 5 ', 'y=1','y=-1'])
plt.show()
xx=np.linspace(2,6,100)
plt.semilogy(xx,dg2(xx))
plt.plot([2,6],[1,1])
plt.plot([2,6],[-1,-1])
plt.legend(['derivata prima di g2 in un intorno di 5 ', 'y=1','y=-1'])

plt.show()

xx=np.linspace(95,105,100)
plt.plot(xx,dg2(xx))
plt.plot([95,105],[1,1])
plt.plot([95,105],[-1,-1])

plt.legend(['Derivata prima di g2 in un intorno di 100','y=1','y=-1'])


# -*- coding: utf-8 -*-
"""
Ese1
"""

import numpy as np
import matplotlib.pyplot as plt
from funzioni_zeri import newton_m, stima_ordine
import sympy as sym
from sympy.utilities.lambdify import lambdify

x=sym.symbols('x')
#x - 2 * sqrt(x-1)
fx= x-2*sym.sqrt(x-1)
dfx=sym.diff(fx,x,1)
print('Derivta prima di f -->', dfx)
#In x=2 si annula sia la funzione che la sua derivata prima,
#la funzione ha in x=2 uno xero con molteplicita=2

#serve per poi fare f(x)


f=lambdify(x,fx,np)
fp=lambdify(x,dfx,np)

x=np.linspace(1,3,100)
plt.plot(x, fp(x))
plt.plot(x,f(x))
#asse delle ascisse
plt.plot(x,[0]*100)
#plt.show()
x0=3
m=2
tolx=1e-12
tolf=1e-12
nmax=100

#Utilizzo il metodo di Newton Modificato con m=2


x1,it,xk= newton_m(f,fp,x0,m,tolx,tolf,nmax)
print('Zero ',x1,' individuato in ', it,' iterazioni')
#Verifico l'ordine di convergenza
ordine=stima_ordine(xk,it)
print('Ordine di convergenza ',ordine)
plt.semilogy(range(it),np.abs(xk))
plt.show()

#Il metodo non converge se scelgo come iterato iniziale x0=1,


#perchè la derivata prima in 1 divergem va a -infinito

Potrebbero piacerti anche