Bonne journée!

J'utilise python v3.8 et je souhaite calculer la plage de valeurs (minimum et maximum) d'une formule donnée avec des limites (également données), par exemple:

formula1: a * sqrt(b/c)

formula2: a^2 * b/1000 + 3 * (a+b)

formula3: (1/(2 * PI * (a * 1000) * (b * 1000)) * 10^12

..with a=[0,5], b=[10,20], c=[30,40]

Je ne suis pas trop familier avec scipy, numpy, sympy .. et je me demande s'il existe un moyen "facile" de calculer simplement la formule avec des valeurs différentes, de l'écrire dans un tableau et d'obtenir le min / max à partir de cela? Le problème que j'ai avec "écrire dans un tableau et obtenir min / max" est qu'il y a des limites [-100000, 100000] avec des nombres flottants donnés et qui généreraient beaucoup trop de valeurs.

Je n'ai pas besoin des informations avec quelles valeurs le minimum / maximum a été atteint, mais seulement quelles valeurs minimum / maximum peuvent être atteintes.

0
Genesis 14 sept. 2020 à 11:19

2 réponses

Meilleure réponse

Symbolique:

Les points maximum et minimum sont appelés points critiques. Pour trouver un point critique, vous devez respecter une dérivée partielle chaque variable (f'_a = df/da, f'_b = df/db, f'_c = df/dc) et résoudre le système d'équations où toutes sont égales à 0. Nous peut faire cela avec sympy.

import sympy as sp

a = sp.Symbol('a', real=True)
b = sp.Symbol('b', real=True)
c = sp.Symbol('c', real=True)

functions = [
    a * sp.sqrt(b / c),
    a**2 * b/1000 + 3*(a+b),
    10**6 / (2 * sp.pi * a * b),
]

for f in functions:
    f_a, f_b, f_c = f.diff(a), f.diff(b), f.diff(c)
    print(f"f(a, b, c) = {f}")
    print(f"f'_a(a, b, c) = {f_a} = 0")
    print(f"f'_b(a, b, c) = {f_b} = 0")
    print(f"f'_c(a, b, c) = {f_c} = 0")
    print("Critical points:", sp.solve([f_a, f_b, f_c], a, b, c))
    print()

Comme vous pouvez le voir si vous exécutez ce code, il n'y a pas de point critique, donc pas de valeur maximale ou minimale absolue pour l'une de ces fonctions dans le domaine réel (il y a deux points critiques pour la deuxième équation dans le domaine imaginaire).

Approche numérique:

En utilisant numpy et pandas, nous pouvons créer une matrice avec toutes les combinaisons possibles, puis appliquer chacune de nos fonctions. Les valeurs maximum et minimum sont par colonne, elles ne sont pas liées entre les colonnes. Comme prévu, les valeurs max et min pour les colonnes a, b et c sont les limites inférieure et supérieure de la plage.

import pandas as pd
from pandas.core.reshape.util import cartesian_product
import numpy as np


# Number of values per range
N = 21

# Functions
functions = [
    lambda row: row['a'] * np.sqrt(row['b'] / row['c']),
    lambda row: row['a']**2 * row['b']/1000 + 3*(row['a']+row['b']),
    lambda row: 10**6 / (2 * np.pi * row['a'] * row['b']),
]

# Lower and upper bounds
a_lower, a_upper = 0, 5
b_lower, b_upper = 10, 20
c_lower, c_upper = 30, 40


def min_max(col):
    return pd.Series(index=['min', 'max'], data=[col.min(), col.max()])


values = [
    np.linspace(a_lower, a_upper, N),
    np.linspace(b_lower, b_upper, N),
    np.linspace(c_lower, c_upper, N),
]

df = pd.DataFrame(cartesian_product(values), index=['a', 'b', 'c']).T
for i, f in enumerate(functions):
    df[f'f_{i + 1}'] = df.apply(f, axis=1)
print(df.apply(min_max))

Production:

       a     b     c       f_1   f_2          f_3
min  0.0  10.0  30.0  0.000000  30.0  1591.549431
max  5.0  20.0  40.0  4.082483  75.5          inf

N = 101 a exactement la même sortie (il faut un peu de temps pour traiter car il doit calculer les formules 101 ^ 3> 1M fois)

0
Adirio 15 sept. 2020 à 08:43

Essayez les solveurs SymPy, ils ont un ensemble de solutions qui peut effectuer les opérations suivantes:

>>> solveset(Eq(x**2, 1), x)
{-1, 1}
1
caldweln 14 sept. 2020 à 08:30