Seite 1 von 1

In "for"-Schleife mit Arrays arbeiten

Verfasst: Montag 5. Mai 2014, 14:18
von alex2007
Folgender umständlicher Code:

Code: Alles auswählen

from numpy import *
b=pi/3.0
a=-pi/2.0
N = int32(2.7*10**linspace(0, 4, 5))
h = (b-a) / N
summe = zeros(5)
for j in range(N[0]):    
    summe[0] += sin(a + h[0]*((2*j - 1)/2))
for j in range(N[1]):    
    summe[1] += sin(a + h[1]*((2*j - 1)/2))
for j in range(N[2]):    
    summe[2] += sin(a + h[2]*((2*j - 1)/2))
for j in range(N[3]):    
    summe[3] += sin(a + h[3]*((2*j - 1)/2))
for j in range(N[4]):    
    summe[4] += sin(a + h[4]*((2*j - 1)/2))
print summe    
Wie bekomm ich das ganze mit einer einzigen Schleife hin?

folgender Code funktioniert leider nicht, wie er soll:

Code: Alles auswählen

from numpy import *
b=pi/3.0
a=-pi/2.0
N = int32(2.7*10**linspace(0, 4, 5))
h = (b-a) / N
summe = zeros(5)
for j in range(N[i]):    
    summe[i] += sin(a + h[i]*((2*j - 1)/2))
denn hier bedeutete "range(N)" wirkliche nur einen Wertebereich, nämlich den des kompletten. Ich bräuchte hier aber etwas wie einen Befehl, der ein Array verwendet, welches quasi so aussieht [range(N[0]), range(N[1],...].

Warum brauch ich das? Nunja, ich will das ganze in eine Funktion einbetten, die am Ende einen Parameter 'anz' beinhaltet, welcher die Anzahl an Werten N und damit an Werten h festlegt. Dazu muss ich das ganze aber irgendwie anders umsetzen. Kann mir hier bitte jemand helfen?

Re: In "for"-Schleife mit Arrays arbeiten

Verfasst: Montag 5. Mai 2014, 14:39
von Sirius3
@alex2007: so wie Du denkst, gar nicht, weil die for-Schleifen über verschieden lange Listen laufen. Sternchenimporte sind bei numpy ganz ganz böse, weil das viele Standardfunktionen überschreibt. Und Wenn Du schon numpy verwendest, solltest Du es auch zum Summieren benutzen.

Code: Alles auswählen

import numpy as np
b=np.pi/3.0
a=-np.pi/2.0
summe = []
for n in np.int32(2.7*10**np.linspace(0, 4, 5)):
    h = (b-a) / n
    j = np.arange(n)
    summe.append(np.sin(a + h*((2*j - 1)/2)).sum())
print summe    

Re: In "for"-Schleife mit Arrays arbeiten

Verfasst: Montag 5. Mai 2014, 14:56
von alex2007
danke erstmal für die schnelle antwort.

summiert die jetzt aber auch von j=0 bis j=n? Mir war nicht ganz klar, dass es funktioniert während der Schleife ein Array zu öfnnen, welche quasi die Liste für n glieder öffnet und dann auch so oft summiert. Also benutzt er dann auch wirklichen jeden Wert j, der aus dem entsprechenden Wert n gewonnen wird?

so funktioniert das dann natürlich mit unterschiedlichen listen.

Danke für diese einfache Lösung, die Verwendung von linspace als Zählvariable und anschließende Überschreibung des Wertes in eine Liste range() innerhalb der Schleife, ist mir komplett neu und wäre mir wohl nicht sofort eingefallen.

Mein Problem im Verständnis, wie das ganze funktioniert:

Ich nehme einen Wert n, gebe j eine Liste mit range(n) und errechne dann die entsprechende summe über meine Formel. Die 'for'-Schleife ist aber nur durch die n Werte bedingt. Wiese benutzt er bei der Summierung erst alle Werte j, bevor er den nächsten Wert n verwendet und j neu überschreibt? Da hakt es im Verständnis! Kannst du mir das erklären?

Re: In "for"-Schleife mit Arrays arbeiten

Verfasst: Montag 5. Mai 2014, 15:13
von BlackJack
@alex2007: Schau Dir doch einfach mal die Teilausdrücke und ihre Ergebnisse an. `j` ist keine Liste die mit `range()` erzeugt wurde, sondern ein Numpy-Array. Das verhält sich anders als Listen. Dieses Verhalten ist der Knackpunkt warum man diese Arrays benutzen möchte, weil die Schleifen dort in den Operationen ”versteckt” sind, und in der Regel in C oder Fortran direkt auf Datentypen laufen, die der Prozessor verarbeiten kann, statt Schleifen in Python-Bytecode der auf Python-Objekten operiert.

Code: Alles auswählen

In [22]: np.arange(27)
Out[22]: 
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23, 24, 25, 26])

In [23]: j = np.arange(27)

In [24]: 2 * j
Out[24]: 
array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32,
       34, 36, 38, 40, 42, 44, 46, 48, 50, 52])

In [25]: 2 * j - 1
Out[25]: 
array([-1,  1,  3,  5,  7,  9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31,
       33, 35, 37, 39, 41, 43, 45, 47, 49, 51])

In [26]: (2 * j - 1) / 2
Out[26]: 
array([-1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
       16, 17, 18, 19, 20, 21, 22, 23, 24, 25])

In [27]: ((b - a) / 27) * (2 * j - 1) / 2
Out[27]: 
array([-0.04848137,  0.04848137,  0.1454441 ,  0.24240684,  0.33936958,
        0.43633231,  0.53329505,  0.63025779,  0.72722052,  0.82418326,
        0.92114599,  1.01810873,  1.11507147,  1.2120342 ,  1.30899694,
        1.40595968,  1.50292241,  1.59988515,  1.69684788,  1.79381062,
        1.89077336,  1.98773609,  2.08469883,  2.18166156,  2.2786243 ,
        2.37558704,  2.47254977])

In [28]: a + ((b - a) / 27) * ((2 * j - 1) / 2)
Out[28]: 
array([-1.66775906, -1.57079633, -1.47383359, -1.37687085, -1.27990812,
       -1.18294538, -1.08598265, -0.98901991, -0.89205717, -0.79509444,
       -0.6981317 , -0.60116896, -0.50420623, -0.40724349, -0.31028076,
       -0.21331802, -0.11635528, -0.01939255,  0.07757019,  0.17453293,
        0.27149566,  0.3684584 ,  0.46542113,  0.56238387,  0.65934661,
        0.75630934,  0.85327208])

In [29]: np.sin(a + ((b - a) / 27) * ((2 * j - 1) / 2))
Out[29]: 
array([-0.9953028 , -1.        , -0.9953028 , -0.98125531, -0.95798951,
       -0.92572397, -0.8847618 , -0.83548781, -0.77836491, -0.71392973,
       -0.64278761, -0.56560688, -0.4831126 , -0.39607977, -0.305326  ,
       -0.21170387, -0.11609291, -0.01939133,  0.07749242,  0.17364818,
        0.26817261,  0.36017772,  0.44879918,  0.53320443,  0.61260055,
        0.68624164,  0.7534359 ])

In [30]: np.sin(a + ((b - a) / 27) * ((2 * j - 1) / 2)).sum()
Out[30]: -7.8944469769042449