Exponentialfunktion

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
fluex
User
Beiträge: 4
Registriert: Donnerstag 17. Mai 2012, 11:15

Hey,

wir sollen im Rahmen unseres Physiklabors unsere Ergebnisse in Pyhton ausgeben.

Dabei bin ich auf folgende Funktion gekommen: T = 296.6-5.53*m.exp(-t/14040)+(P/(5.3*0.169))*-(1-m.exp(t*-6.42**-5))
Leider kriege ich diese Funktion seit Stunden nicht zum laufen!!

Mit folgendem -Code habe ich es versucht:

Code: Alles auswählen

import math as m
import matplotlib.pyplot as plt
import numpy as np
P = 35
t = [1.0 ,2.0 ,3.0 ,4.0 ,5.0]
t = np.array(t)
#Die Liste als array habe ich gemacht, weil sonst folgender fehler kommt:
    #TypeError: bad operand type for unary -: 'list'

T = 296.6-5.53*m.exp(-t/14040)+(P/(5.3*0.169))*-(1-m.exp(t*-6.42**-5)) 

plt.plot(T,t)
plt.show()
Leider kommt dabei immer folgender Fehler

Code: Alles auswählen

TypeError: only length-1 arrays can be converted to Python scalars
In google hab ich den hinweis gefunden, dass ich statt m.exp, folgenden Ausdruck verwende: numeric.exp
allerdings hat auch das nicht geholfen.

Kann mir vl jmd einen hinweis geben, was da falsch läuft. Irgendwie komm ich mit python noch nicht so klar :-/



grüße
fluex
BlackJack

@fluex:

Du hättest selbst schon mal den Fehler auf einen Teilausdruck eingrenzen können.

Code: Alles auswählen

In [647]: t
Out[647]: array([ 1.,  2.,  3.,  4.,  5.])

In [648]: -t
Out[648]: array([-1., -2., -3., -4., -5.])

In [649]: -t / 14040
Out[649]: 
array([ -7.12250712e-05,  -1.42450142e-04,  -2.13675214e-04,
        -2.84900285e-04,  -3.56125356e-04])

In [650]: m.exp(-t / 14040)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/home/bj/<ipython console> in <module>()

TypeError: only length-1 arrays can be converted to Python scalars
`math` kennt keine Arrays, folglich kommt `math.exp()` auch nicht mit einem `numpy.array` als Argument klar. Es versucht das Array in einen Skalarwert zu wandeln, das geht aber nur mit Arrays die ”klein” genug sind:

Code: Alles auswählen

In [651]: float(np.array([42.0]))
Out[651]: 42.0

In [652]: float(np.array([42.0, 23.0]))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/home/bj/<ipython console> in <module>()

TypeError: only length-1 arrays can be converted to Python scalars
Du verwendest `numpy` und nicht `numeric` (das ist eine Vorgängerbibliothek von `numpy`), also müsstest Du `numpy.exp()` verwenden.

Code: Alles auswählen

In [653]: np.exp(-t / 14040)
Out[653]: array([ 0.99992878,  0.99985756,  0.99978635,  0.99971514,  0.99964394])
fluex
User
Beiträge: 4
Registriert: Donnerstag 17. Mai 2012, 11:15

Vielen Dank für die schnelle Antwort!
Das Numpy der Nachfolger von Numeric ist, wusste ich nicht. Danke für den Hinweis!
Wenn ich nun

Code: Alles auswählen

np.exp
schreibe, kommt immerhin schonmal eine Ausgabe.
Ist eigentlich das Modul math im Modul Numpy inbegriffen? Könnte ich also immer statt math auch numpy nehmen?

Und noch eine weitere Frage:
Warum muss ich in diesem Fall jetzt die Liste in einen Array umwandeln? Wenn ich dies nämlich nicht mache, kommt folgender Fehler

Code: Alles auswählen

Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/dist-packages/spyderlib/widgets/externalshell/introspection.py", line 65, in run
    self.send_socket(shell_id, conn)
  File "/usr/lib/python2.7/dist-packages/spyderlib/widgets/externalshell/introspection.py", line 49, in send_socket
    shell.set_introspection_socket(sock)
  File "/usr/lib/python2.7/dist-packages/spyderlib/widgets/externalshell/pythonshell.py", line 246, in set_introspection_socket
    'set_remote_view_settings()', settings=[settings])
  File "/usr/lib/python2.7/dist-packages/spyderlib/utils/bsdsocket.py", line 67, in communicate
    return read_packet(sock)
  File "/usr/lib/python2.7/dist-packages/spyderlib/utils/bsdsocket.py", line 36, in read_packet
    dlen, = struct.unpack("l", datalen)
error: unpack requires a string argument of length 8
Außerdem versteh ich auch den Fehler nicht... Was bedeutet diese Meldung?

Grüße fluex
BlackJack

@fluex: Nein als inbegriffen würde ich das nicht bezeichnen, auch wenn vieles was in `math` für Skalare definiert ist, in `numpy` für Arrays (und Skalare) vorhanden ist. Aber nicht alles. Schauen wir mal was in `math` an Namen definiert ist und verwenden dann Mengenoperationen um herauszufinden welche Namen davon in `numpy` nicht vorhanden sind:

Code: Alles auswählen

In [665]: dir(math)
Out[665]: 
['__doc__',
 '__name__',
 '__package__',
 'acos',
 'acosh',
 'asin',
 'asinh',
 'atan',
 'atan2',
 'atanh',
 'ceil',
 'copysign',
 'cos',
 'cosh',
 'degrees',
 'e',
 'exp',
 'fabs',
 'factorial',
 'floor',
 'fmod',
 'frexp',
 'fsum',
 'hypot',
 'isinf',
 'isnan',
 'ldexp',
 'log',
 'log10',
 'log1p',
 'modf',
 'pi',
 'pow',
 'radians',
 'sin',
 'sinh',
 'sqrt',
 'tan',
 'tanh',
 'trunc']

In [666]: set(dir(math)) - set(dir(numpy))
Out[666]: 
set(['acos',
     'acosh',
     'asin',
     'asinh',
     'atan',
     'atan2',
     'atanh',
     'copysign',
     'factorial',
     'fsum',
     'pow'])
Zumindest unter diesen Namen sind die Funktionen nicht in `numpy` enthalten.

Die `numpy`-Funktionen liefern auch bei Skalaren als Argumenten einen anderen Typ als Ergebnis. Das kann in bestimmten Situationen zu subtil unterschiedlichem Verhalten führen:

Code: Alles auswählen

In [668]: type(math.sin(42.0))
Out[668]: <type 'float'>

In [669]: type(numpy.sin(42.0))
Out[669]: <type 'numpy.float64'>

In [670]: math.sin(42.0) * [1, 2, 3]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/home/bj/<ipython console> in <module>()

TypeError: can't multiply sequence by non-int of type 'float'

In [671]: numpy.sin(42.0) * [1, 2, 3]
Out[671]: []
Ich würde `numpy` nur verwenden, wenn es auch wirklich um Arrays geht.

Zur weiteren Frage: Was ist „in diesem Fall”? Um welchen Quelltext geht es und womit wird der ausgeführt. Der Traceback hat was mit Threads und Socket-Kommunikation zu tun, die wahrscheinlich nicht Bestandteil Deines Programms sind und auch nicht ins Spiel kommen, wenn Du Deinen Code einfach mit Python ausführst. Kann es sein dass Du eine spezielle IDE verwendest, von der dieser Fehler kommt?
Antworten