2015-07-15 47 views
5

Ich habe eine Funktion für mit ich muss eine unendliche Summe auf (über alle ganzen Zahlen) numerisch zu tun. Die Summierung muss nicht immer konvergieren, da ich interne Parameter ändern kann. Die Funktion sieht aus wie,Unendliche Summation in Python

m(g, x, q0) = sum(abs(g(x - n*q0))^2 for n in Integers) 
m(g, q0) = minimize(m(g, x, q0) for x in [0, q0]) 

einen Pythonic Pseudo-Code mit

Mit Scipy Integrationsmethoden, ich war nur der n Bodenbelag und wie für eine feste x Integration

m(g, z, q0) = integrate.quad(lambda n: 
          abs(g(x - int(n)*q0))**2, 
          -inf, +inf)[0] 

Dies funktioniert ziemlich gut, aber dann muss ich Optimierung auf dem x als eine Funktion von x tun, und dann eine andere Summe auf dem machen, die ein Integral einer Optimierung eines Integrals ergibt. Es dauert ziemlich lange.

Kennen Sie einen besseren Weg, die Summierung schneller zu machen? Handcodierung schien es langsamer zu gehen.

Derzeit arbeite ich mit

g(x) = (2/sqrt(3))*pi**(-0.25)*(1 - x**2)*exp(-x**2/2) 

aber die Lösung sollte allgemein sein

Das Papier dieses von ist kommt „Die Wavelet-Transformation, Zeit-Frequenz-Lokalisierung und Signalanalyse“ von Daubechies (IEEE 1990)

Danke

+0

Ist 'beta (s)' nur eine skalare Konstante? Der 's' Parameter scheint nichts zu tun. –

+0

Also, was ist 'g (x)'? –

+0

Oh, tut mir leid, ich habe die eine Hälfte der einen und die andere Hälfte der obigen Gleichung kopiert. Lass mich das reparieren. g (x) ist willkürlich, derzeit in meinem Code ist es die zweite Ableitung des Gaußschen. –

Antwort

4

Dank all dem nützlichen Kommentar habe ich meinen eigenen Summator geschrieben, der ziemlich schnell zu laufen scheint. Es hat jemand irgendwelche Empfehlungen, um es besser zu machen, ich werde sie gerne nehmen.

Ich werde dies an dem Problem, an dem ich arbeite, testen und sobald es Erfolg zeigt, werde ich es als funktional bezeichnen.

def integers(blk_size=100): 
    x = arange(0, blk_size) 
    while True: 
     yield x 
     yield -x -1 
     x += blk_size 

#                                                    
# For convergent summation                                             
# on not necessarily finite sequences                                           
# processes in blocks which can be any size                                         
# shape that the function can handle                                           
#                                                    
def converge_sum(f, x_strm, eps=1e-5, axis=0): 
    total = sum(f(x_strm.next()), axis=axis) 
    for x_blk in x_strm: 
     diff = sum(f(x_blk), axis=axis) 
     if abs(linalg.norm(diff)) <= eps: 
      # Converged                                              
      return total + diff 
     else: 
      total += diff 
+0

Sehr schön. Ich habe gerade ein paar Fehler in Ihrem Einzug behoben. –

+0

'np.linalg.norm' ist ziemlich langsam - Sie könnten wahrscheinlich wesentlich besser machen, indem Sie die Norm selbst nehmen, z. 'np.sqrt (diff.dot (diff))' für 1D –

+0

Danke. Ich entschied mich, bei linalg.norm zu bleiben, da ich höhere dimensionale Strukturen verwende (3,4,5 ndarrays). Es mag langsam sein, aber alles läuft bemerkenswert schnell. Für die Aufzeichnung konvergiert der obige Code normal, aber nicht vollständig robust. 90% -ish Prozent der Zahlen, die ich bekomme, sind gleich den Zahlen in der Zeitung, aber für bestimmte Fälle bekomme ich andere Werte, als ob ich Bereiche mit hoher Dichte in der Näherung –

2

g(x) ist fast sicher Ihr Engpass. Eine sehr schnelle und unsaubere Lösung wäre es vektorisieren auf einem Array von ganzen Zahlen zu arbeiten, dann np.trapz verwenden Sie das Integral mit der Trapezregel zu schätzen:

import numpy as np 

# appropriate range and step size depends on how accurate you need to be and how 
# quickly the sum converges 
xmin = -1000000 
xmax = 1000000 
dx = 1 

x = np.arange(xmin, xmax + dx, dx) 
gx = (2/np.sqrt(3)) * np.pi**(-0.25)*(1 - x**2) * np.exp(-x**2/2) 
sum_gx = np.trapz(gx, x, dx) 

Abgesehen davon, könnten Sie g(x) neu schreiben Verwenden Sie Cython oder Numba, um es zu beschleunigen.

+0

Danke. Ich benutzte eine vektorisierte Version von g (x), aber der Optimierungsschritt zerstört die Vektornatur. Ich untersuche mit einem anderen Optimierer, der Bounded Vector-Optimierung (scipy.optimize.differential_evolution) tun kann. Dann kann ich alles vektorisieren. Außerdem denke ich numerisch, es ist besser, nur den gx-Vektor zu summieren.Trapazoide Integration könnte Kanten zu viel schneiden –

+0

Auch weiß ich differential_evolution ist langsam, aber mein Problem ist nicht unbedingt konvex, also brauche ich begrenzte globale Minimierung –

+0

Wenn Sie interessiert sind, habe ich eine Antwort mit einer Lösung, die die Summierung für vektorisierte Funktionen tut . –