um eine Implementierung eines Partikelfilters schneller zu machen, habe ich auf cython zurückgegriffen. Die erreichten Geschwindigkeitssteigerungen bleiben jedoch weit hinter dem zurück, was ich in den Tutorials gelesen habe (maximal Faktor 4). Hier kommt der Cython code für die beiden Funktionen:
Code: Alles auswählen
import cython
import numpy
cimport numpy
import math
import random
# http://docs.cython.org/src/tutorial/numpy.html
DTYPE = numpy.float64
ctypedef numpy.float64_t DTYPE_t # whyever... a compile-time type with _t suffix is necessary. (See link above)
#~ DTYPE2 = numpy.long
#~ ctypedef numpy.long_t DTYPE2_t
@cython.boundscheck(False) # turn of bounds-checking for entire function
def reCalcEinenSensorCython(unsigned int no_particles, int x, int y, numpy.ndarray[DTYPE_t, ndim=2] particleNumpy, numpy.ndarray[long, ndim=2] XBlackToWhite, numpy.ndarray[long, ndim=2] XWhiteToBlack, numpy.ndarray[long, ndim=2] YBlackToWhite, numpy.ndarray[long, ndim=2] YWhiteToBlack):
cdef numpy.ndarray[int, ndim=1] l # changed arrays in Schachbrett to numpy arrays
cdef numpy.ndarray[int, ndim=2] vektorKleiner
cdef numpy.ndarray[int, ndim=2] vektorGroesser
cdef numpy.ndarray[int, ndim=2] vektor
cdef numpy.ndarray[int, ndim=1] vektorMitte
cdef numpy.ndarray[int, ndim=2] vektorKleinereDist
for l in XBlackToWhite:
particleNumpy[0:no_particles,14] = particleNumpy[0:no_particles,x]-l[0]
vektorKleiner = numpy.array(numpy.nonzero(particleNumpy[0:no_particles,y]<l[1]))
vektorGroesser = numpy.array(numpy.nonzero(particleNumpy[0:no_particles,y]>l[2]))
vektor = numpy.array(numpy.nonzero(particleNumpy[0:no_particles,y]>=l[1]))
vektorMitte = numpy.array(numpy.nonzero(particleNumpy[vektor,y]<=l[2])[1])
particleNumpy[vektorMitte,13] = 0
particleNumpy[vektorKleiner,13] = particleNumpy[vektorKleiner,y] - l[1]
particleNumpy[vektorGroesser,13] = particleNumpy[vektorGroesser,y] - l[2]
particleNumpy[0:no_particles,14] = (particleNumpy[0:no_particles,13]*particleNumpy[0:no_particles,13]+particleNumpy[0:no_particles,14]*particleNumpy[0:no_particles,14])**0.5
vektorKleinereDist = numpy.array(numpy.nonzero(particleNumpy[0:no_particles,3]>particleNumpy[0:no_particles,14]))
particleNumpy[vektorKleinereDist,3] = particleNumpy[vektorKleinereDist,14]
return particleNumpy, vektorKleinereDist
@cython.boundscheck(False) # turn of bounds-checking for entire function
def sensorPart4Cython(unsigned int no_particles, numpy.ndarray[DTYPE_t, ndim=2] particleNumpy, unsigned int particlefilterStepcount):
cdef float start = 0.0
cdef int b
cdef int a
cdef int pos
cdef int deltapos
cdef float pGewichtung
cdef int c
cdef list rangeList = range(no_particles) # can I somehow define this as list of integers???
for b in rangeList:
a = b - 1
particleNumpy[a,13] = start
start = start + particleNumpy[a,4]
particleNumpy[a,14] = start
neueParticel = numpy.array([numpy.random.normal(800, 50, no_particles), numpy.random.normal(300, 100, no_particles), numpy.random.normal(math.pi, math.pi/16, no_particles), range(no_particles), range(no_particles), range(no_particles), range(no_particles), range(no_particles), range(no_particles), range(no_particles), range(no_particles), range(no_particles), range(no_particles), range(no_particles), range(no_particles), range(no_particles), range(no_particles), range(no_particles)], float)
neueParticel = neueParticel.transpose()
c = 0
for b in rangeList:
a = b - 1
pos = int(no_particles/2)
deltapos = int(no_particles/2)
pGewichtung = random.random() * start
while not(particleNumpy[pos,13] <= pGewichtung and pGewichtung<=particleNumpy[pos,14]):
particlefilterStepcount = particlefilterStepcount + 1
if deltapos!=1:
deltapos = int(deltapos / 2)
if deltapos<1:
deltapos=1
if particleNumpy[pos,13]>=pGewichtung:
pos = pos-deltapos
else:
pos = pos+deltapos
#x, y, phi, Distanz, Gewichtung, xSensor, ySensor, xtemp, ytemp, calcTemp
neueParticel[c,0] = particleNumpy[pos,0] + random.gauss(0,1)
neueParticel[c,1] = particleNumpy[pos,1] + random.gauss(0,1)
neueParticel[c,2] = particleNumpy[pos,2] + random.gauss(0,math.pi/32)
c = c + 1
return neueParticel, particlefilterStepcount
- wie kann ich mir die Version meiner Cython Installation ausgeben lassen?
- wie kann ich eine List mit integer Einträgen als cdef definieren (Siehe auch Kommentar im Code)?
und schließlich bin ich für Eure allgemeinen Hinweise dankbar, die mir den Code schneller machen!
Vielen Dank schon jetzt.
BG
Felix