J'écris généralement un simulateur d'ordinateur quantique en Python. Pour cette raison, les nombres complexes sont très souvent utilisés.
Python et numpy prennent également en charge les nombres complexes, donc ce n'est pas trop un problème, mais il y a quelques pièges, donc je vais les résumer tous.
C'est celui que vous trouvez normalement dans la référence. Révisez légèrement.
En mathématiques, i est souvent utilisé pour les unités imaginaires, mais en Python, «1j» est utilisé. (Dans des domaines comme l'électricité, j'ai vu que i est utilisé pour le courant, donc l'unité imaginaire est définie comme j, mais je ne sais rien d'autre dans les autres domaines)
Vous pouvez également écrire quelque chose comme «2j» ou «1.23j». (Signifie normalement deux fois plus que «1j», 1,23 fois) Alors que «1» et «1.» ont des types différents, «1j» et «1.j» sont tous les deux identiques.
ʻA + b * 1. jpeut aussi être écrit comme
complexe (a, b)` avec a et b comme flottants.
.real
, .imag
et prenez un conjugué complexe avec conjugate ()
«(1 + 2j) .real» est «1», «(1 + 2j) .imag» est «2». Notez que ce n'est pas une méthode, donc n'ajoutez pas ()
.
Les conjugués complexes utilisent «.conjugate ()», comme «(1 + 2j) .conjugate ()». Puisqu'il s'agit d'une méthode, ()
est obligatoire.
Au fait, .real
, .imag
, conjugate ()
peuvent en fait être utilisés pour float et int.
Même avec numpy, vous pouvez utiliser des nombres complexes normalement, tels que np.array ([1 + 2j, 3, 4j, 5 + 6.7j])
. À ce stade, «dtype» est par défaut «complex128».
«.real», «.imag», «.conjugate ()» peuvent également être utilisés pour les tableaux numpy.
De plus, dans numpy, vous pouvez utiliser .conj ()
au lieu de .conjugate ()
.
De plus, il faut utiliser «.conj (). T» pour prendre le conjugué Elmeet de la matrice, ce qui est un peu gênant.
Avec np.matrix
, c'était possible avec .H
. Il ne semble pas être dans np.array
.
cmath
au lieu de math
Utilisez ʻimport cmath au lieu de ʻimport math
.
Alors que la fonction math
prend des nombres réels dans la définition et la plage, cmath
contient également des nombres complexes dans la définition et la plage.
Voir Documentation officielle pour plus de détails.
Il existe également des fonctions utiles telles que phase ()
qui trouve l'angle de déviation d'un nombre complexe, polar ()
qui renvoie un tapple de rayon et d'angle de déviation, et rect ()
qui crée un nombre complexe à partir du rayon et de l'angle de déviation. ..
J'écrirai quelques pièges et comment les gérer.
Python convertit implicitement le type sans écrire le type par vous-même, mais dans numpy, tableau a un type et le type de tableau ne change pas arbitrairement. (La même chose est vraie si le tableau int ne devient pas un flottant)
a = np.array([1., 2.]) #dtype est float64
a *= 1j
# UFuncTypeError: Cannot cast ufunc 'multiply' output from dtype('complex128') to dtype('float64') with casting rule 'same_kind'
Pour éviter que cela ne se produise
Spécifiez le type depuis le début comme np.array ([1., 2.], dtype = np.complex128)
Il est nécessaire d'inclure des nombres complexes depuis le début, tels que np.array ([1 + 0j, 2.], dtype = np.complex128)
.
C'est vraiment un piège.
Le produit interne du vecteur complexe est la somme du produit du conjugué complexe de $ u $ et du produit de chaque composant de $ v $, tel que $ u \ cdot v = \ sum_ {i = 1} ^ n u_i ^ * v_i $. C'est normal, mais dans «np.dot», la somme des produits de chaque composant est prise telle quelle sans prendre le conjugué complexe. Si vous avez vraiment besoin d'utiliser np.dot
, prenez vous-même le conjugué complexe.
D'un autre côté, si vous utilisez np.vdot
, vous pouvez obtenir correctement le produit interne même s'il s'agit d'un vecteur complexe.
Evidemment pour quiconque traite des nombres complexes dans d'autres langues. Les nombres complexes ne peuvent pas être comparés.
Plus précisément, il n'est pas possible de faire une comparaison de grandeur de "type complexe", donc même si le programmeur sait que le résultat du calcul est un nombre réel, s'il s'agit d'un type de nombre complexe pour l'ordinateur, il ne peut pas être comparé. Ce doit être un nombre réel, tel que «.real».
Puisque np.abs
calcule en interne quelque chose comme sqrt (real ** 2 + imag ** 2)
, il est inutile de le mettre au carré.
D'un autre côté, si vous écrivez un calcul comme ʻarr.real ** 2 + arr.imag ** 2` du côté Python, il ne sera pas calculé sur place, ce qui entraînera une allocation de mémoire gaspillée.
J'ai déjà fait des recherches, mais StackOverflow dit que numba peut être utilisé -of-complexe-numpy-ndarray). Il semble qu'il n'y ait pas de moyen surprenant de le faire en place sans calcul plat ouvert inutile uniquement avec Python et numpy.