Sensitivität Analyse mit SALib

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
qwertz
User
Beiträge: 4
Registriert: Freitag 22. Januar 2016, 15:15

Hey ich möchte eine Sensitivität analyse durchführen und dazu habe ich das Modul SALib gefunden.
Nun möchte ich dieses nutzen um meine Variablen in den DGL meines Programms auf ihrere Sensitivität zu prüfen.
Soweit habe ich es auch geschafft, doch leider gibt mir python nun als Lösung [nan,nan,nan] aus und keinerlei Fehlermeldung

Es wäre schön wenn mir jmd helfen könnte.
Hier ein Link zur Seite von SALib http://salib.readthedocs.org/en/latest/

Hier ist der CODE:

Code: Alles auswählen

from SALib.sample import saltelli
from SALib.analyze import sobol
from pylab import *
from scipy.integrate import odeint

Tu=20.
time=600#only time at one point here: 10min


def dTdt(T,t,P):# DGL Sensitiv P to analysis
    dT=zeros(2)
    dT[0]=P[0]*(T[1]-T[0])+P[2]
    dT[1]=P[1]*(Tu-T[1])+P[0]*(T[0]-T[1])
    return dT

T0=array([Tu,Tu]) 
def odefunk(values):
    dTlist=zeros(len(param_values))#8000=N*(2*num_vars+2) with N=1000 num_vars=3    
    for i,P in enumerate(values):#loop the odeintfunk with values
        Ti=odeint(dTdt,T0,time,args=(P,))
        dTlist[i]=Ti[:,0] #odeint creats a array (2,t) but Salib needs a single value
    return dTlist


# Define the model inputs
problem = {
    'num_vars': 3,
    'names': ['P0', 'P1', 'P2'],
    'bounds': [[ -10,30],
               [ 4, 64],
               [ 16,155]]
}

# Generate samples for N=1000 it prints [nan,nan,nan] 
param_values = saltelli.sample(problem, 1000, calc_second_order=True)


# Perform analysis
Solve=odefunk(param_values)
Si = sobol.analyze(problem, Solve, print_to_console=False)

# Print the first-order sensitivity indices
print Si['S1']
Zuletzt geändert von Anonymous am Freitag 22. Januar 2016, 15:52, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@qwertz: Das beschriebene (Teil)Problem kann ich hier nicht nachvollziehen:

Code: Alles auswählen

In [5]: from SALib.sample import saltelli

In [6]: problem = {
   ...:     'num_vars': 3,
   ...:     'names': ['P0', 'P1', 'P2'],
   ...:     'bounds': [[ -10,30],
   ...:                [ 4, 64],
   ...:                [ 16,155]]
   ...: }

In [7]: saltelli.sample(problem, 1000, calc_second_order=True)
Out[7]: 
array([[  -1.2109375 ,    9.80078125,   88.07910156],
       [  17.0703125 ,    9.80078125,   88.07910156],
       [  -1.2109375 ,   20.81640625,   88.07910156],
       ..., 
       [   9.66796875,   40.70898438,  118.28173828],
       [   9.66796875,   52.13476562,   34.66455078],
       [   9.66796875,   52.13476562,  118.28173828]])
qwertz
User
Beiträge: 4
Registriert: Freitag 22. Januar 2016, 15:15

@BlackJack

In problem werden die Variablen, welche ich auf Sensitivität analysieren will aufgegeben, dabei handelt es sich um 3 variablen. (P[1],P[2],und P[3])
Anschließend wird für jede Variable ein Intervall festgelegt: Bsp. -10<P[1]<30

saltelli.sample generiert nun eine matrix in der die Samples gespeichert werden ..> N(2*D+2) N=1000 D=3(anzahl der Variablen) N=1000
Das array was du ausgibst ist demnach eine (N*(2D+2),D) Matrix also --> (8000,3)

Code: Alles auswählen

In [5]: from SALib.sample import saltelli
 
In [6]: problem = {
   ...:     'num_vars': 3,
   ...:     'names': ['P0', 'P1', 'P2'],
   ...:     'bounds': [[ -10,30],
   ...:                [ 4, 64],
   ...:                [ 16,155]]
   ...: }
 
In [7]: saltelli.sample(problem, 1000, calc_second_order=True)
Out[7]:
array([[  -1.2109375 ,    9.80078125,   88.07910156],
       [  17.0703125 ,    9.80078125,   88.07910156],
       [  -1.2109375 ,   20.81640625,   88.07910156],
       ...,
       [   9.66796875,   40.70898438,  118.28173828],
       [   9.66796875,   52.13476562,   34.66455078],
       [   9.66796875,   52.13476562,  118.28173828]])
BlackJack

@qwertz: Ich weiss das alles, aber genau das ist doch der Punkt: Du schreibst bei Dir ergäbe das eine Liste mit drei NaN-Werten anstelle von dem Array‽
qwertz
User
Beiträge: 4
Registriert: Freitag 22. Januar 2016, 15:15

@BlackJack

Nein, die "first-order sensitivity indices" werden mir für alle drei variablen mit [nan,nan,nan] angegeben :K

Code: Alles auswählen

# Print the first-order sensitivity indices
print Si['S1']
BlackJack

@qwertz: Dann ist der Kommentar an der Stelle aber sehr irreführend. Soll das so, dass `Solve` ausschliesslich aus lauter 20-Werten besteht?
qwertz
User
Beiträge: 4
Registriert: Freitag 22. Januar 2016, 15:15

BlackJack hat geschrieben:@qwertz: Dann ist der Kommentar an der Stelle aber sehr irreführend. Soll das so, dass `Solve` ausschliesslich aus lauter 20-Werten besteht?
Ich bin ganz neu was Python angeht. Also ich verstehe das folgendermaßen:
Solve müsste die Funktion sein die an odefunk--> param_values übergibt. Das sind die 3 Variablen mit unterschiedlichen werten. Wie gesagt 8000 werte...
Und ich denke das was du ansprichst ist genau der Fehler- Ich möchte ja mit der For-schleife die param_values durchgehen und für meinen P vektor einsetzen. Demnach müsste meine Schleife über odeint falsch sein oder die Parameter werden falsch übergeben...

Also letzt endlich Nein es sollen nicht nur 20er werte sein

Code: Alles auswählen

Solve=odefunk(param_values)
Si = sobol.analyze(problem, Solve, print_to_console=False)
Antworten