2017-10-08 11 views
1

J'essaie de faire une simulation mathématique pour trouver quand une condition est remplie. Mon approche était de définir les conditions et de faire une boucle while qui augmente les valeurs de x et y. Voir le code ci-dessous:Calculer la fonction avec toutes les valeurs dans la gamme?

# Initialize the variables. 

x1list = [] 
y1list = [] 
x2list = [] 
y2list = [] 

x = 0 
y = 0 
i = 0 

while i < 10: 

    # Update data. 
    i += 1 
    x += .1 
    y += .1 

    func1 = x + y - 1 
    func2 = x * y 

    cond1 = func1 < func2 < 1 

    if cond1: 
    x1list.append(x) 
    y1list.append(y) 

Le problème avec ce code est qu'il ne calcule que la condition lorsque x et y augmentation au même rythme. Bien sûr, je pourrais changer les taux, mais cela ne résoudrait pas vraiment le problème.

Ce que je veux faire est de calculer la condition dans une plage, disons x (-10,10) et y (-10,10). Je pensais à faire un tableau avec toutes les valeurs x et un autre avec toutes les valeurs y, mais je ne sais pas comment calculer la condition avec toutes ces valeurs.

Une autre idée que j'avais était de prendre une seule valeur de x et de la tester avec toutes les valeurs y, puis d'augmenter x et de tester encore et encore.

Comment aborder ce problème?

Répondre

1

Méthode 1: « simulation » 2D grille

Je pensais à faire un tableau avec toutes les valeurs x et l'autre avec toutes les valeurs y, mais, alors, je ne sais pas comment calculer la condition avec toutes ces valeurs.

import numpy as np 

x = np.arange(-10, 10, 0.1) 
y = np.arange(-10, 10, 0.1) 

# Create 2D simulation meshes for x and y. 
# You can read the API entry for meshgrid to learn about options for index 
# ordering, mesh sparsity, and memory copying 
X, Y = np.meshgrid(x, y) 

func1 = X + Y - 1 
func2 = X * Y 
cond = np.logical_and(func1 < func2, func2 < 1.0) # intrinsic `and` does not work here 

# now cond can be used as a 'mask' for any masked-array operations on X and Y 
# including for numpy boolean indexing: 
print('(X, Y) pairs') 
for xy_pair in zip(X[cond], Y[cond]): 
    print xy_pair 

Méthode 2: boucles imbriquées

Une autre idée que je devais était de prendre une seule valeur de x et de le tester avec toutes les valeurs y, puis augmenter à nouveau x et d'essai et encore.

import numpy as np # no slower or memory-intensive than `from numpy import arange` 

X = [] 
Y = [] 
for y in np.arange(-10, 10, 0.1): 
    for x in np.arange(-10, 10, 0.1): 
     if (x+y-1 < x*y) and (x*y < 1.0): 
      X.append(x) 
      Y.append(y) 

print('(X, Y) pairs') 
for xy_pair in zip(X, Y): 
    print xy_pair 

Quelle méthode choisir?

Comment aborder ce problème?

Cela dépend entièrement de ce que vous voulez faire avec (x, y) paires qui évaluent à True. Si vous éditez votre question avec un peu plus de conseils, il pourrait devenir évident quelle est la solution la plus simple pour votre cas d'utilisation.

Par exemple, Méthode 1 fournit des tableaux 2D pour tracer l'espace de solution tandis que Méthode 2 fournit python compact list s pour databasing.

Attention: les opérateurs conditionnels

Il faut aussi souligner que les expressions mathématiques avec plusieurs opérateurs conditionnels ne font pas de sens en Python. Cette ligne:

cond1 = func1 < func2 < 1

si évaluée en utilisant l'ordre standard des opérations comme cond1 = (func1 < func2) < 1 aurait une évaluation intermédiaire de cond1 = (True/False) < 1, qui implicitement refondre True comme 1 et False comme 0, mais ne serait pas évaluer correctement l'expression mathématique func1 < func2 < 1.

EDIT:

@ (Eric DUMINIL) les réponses de fournir des concepts alternatifs pour résoudre le problème mathématique sous-jacente, les deux méthodes ci-dessus suppose que votre problème devait être résolu numériquement sur un maillage discret, et ayant ces points de solutions discrètes étaient nécessaires pour tout code suivi.

@ La réponse d'Uriel peut sembler fonctionner, mais voir ma note sur les opérateurs conditionnels pour savoir pourquoi cela peut être trompeur.

En outre, j'ai initialement tapé and pour combiner les instructions conditionnelles 2D, mais cela est incorrect et entraîne une erreur. Utilisez np.logical_and à la place.

1

Pour ce type de problème, vous ne voulez pas itérer aveuglément. Tout d'abord, vous pouvez rechercher des solutions évidentes: x = 0 et y = 0 en est une. Vous pouvez utiliser sympy pour essayer de trouver des solutions générales. Wolfram Alpha est également un excellent outil pour ces tâches, et trouve cette région:

enter image description here

Si ces outils ne peuvent pas trouver une solution algébrique, vous pouvez utiliser scipy.optimize pour trouver des résultats numériques:

from scipy.optimize import minimize 
def f(x): 
    return (x[0] + x[1] - 1)**2 + (x[0] * x[1])**2 

minimize(f, [0,0]) 

Il produit:

status: 0 
    success: True 
    njev: 6 
    nfev: 24 
hess_inv: array([[ 0.59518944, -0.40481056], 
     [-0.40481056, 0.59518944]]) 
     fun: 0.050945906253583216 
     x: array([ 0.4533971, 0.4533971]) 
    message: 'Optimization terminated successfully.' 
     jac: array([ -2.88896263e-06, -2.88896263e-06]) 

C'est un peu exagéré pour cet exemple, mais cela semble prometteur résultats pour des fonctions plus complexes.