Python + minGW

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
Benutzeravatar
__deets__
User
Beiträge: 2175
Registriert: Mittwoch 14. Oktober 2015, 14:29

Re: Python + minGW

Beitragvon __deets__ » Mittwoch 27. Dezember 2017, 11:56

Natürlich tut der das. Weil er Informationen sammelt, die man danach auswertet um rauszufinden, wo man bottle necks hat.
drankaner
User
Beiträge: 13
Registriert: Freitag 27. Oktober 2017, 13:22

Re: Python + minGW

Beitragvon drankaner » Mittwoch 27. Dezember 2017, 13:06

drankaner hat geschrieben:@sirius3: Ich habe etwa drei Zeitfresser:
1. sind die Matrixmultiplikationen von oben ca. 40%,
2. Ist die Umrechnung in Kamerakoordinaten oben: calculatePointInCameraCoordSys.py diese benötigt etwa 35% der Zeit und
3. ist die Berechnung der möglichen Camerasettings (Also welche Kamera können mir zudem Punkt überhaupt einen Anteil liefern) ca 15%.

Die letzte Funktion hatte ich noch nicht gepostet.

Code: Alles auswählen

def combinations(objects, k):
    if objects == [] or len(objects) < k or k == 0:
   yield []
    elif len(objects) == k:
        yield objects
    else:
        for combination in combinations(objects[1:], k-1):
            yield [objects[0]] + combination
        for combination in combinations(objects[1:], k):
            yield combination

def Cameraset(validCams,validCamsNo,Cams):
        invalidCams=[]
   
        combs=list(combinations([0,1,2,3,4,5,6,7],validCamsNo))
        #int(math.factorial(Cams)/(math.factorial(Cams-validCamsNo)*math.factorial(validCamsNo)))
        for x in range(0,len(validCams)):
            if validCams[x]==0:
                invalidCams.append(x)
        for y in range(0,len(invalidCams)):
            i=0
            possible=len(combs)
            for x in range(0,possible):
                if combs[x-i].count(invalidCams[y])>0:
                    combs.pop(x-i)
                    i+=1
        return combs


Wobei diese, auch denk geringsten Zeitaufwand hat.


Das ganze konnte ich nun doch nochmal effizienter machen, sodass ich hier nun keine Zeit mehr verschwende. Nun ist die Zeitaufteilung wiefolgt:
    1. sind die Matrixmultiplikationen von oben ca. 50%,
    2. Ist die Umrechnung in Kamerakoordinaten oben: calculatePointInCameraCoordSys.py diese benötigt etwa 45% der Zeit
Bei nun noch etwa 16 Minuten.

Dann werd eich jetzt mal den Profiler duchlaufen lassen.
Sirius3
User
Beiträge: 7067
Registriert: Sonntag 21. Oktober 2012, 17:20

Re: Python + minGW

Beitragvon Sirius3 » Mittwoch 27. Dezember 2017, 13:15

@drankaner: wie sieht denn jetzt Dein Code aus, und welche Zeilen brauchen wie lange?

»combinations« gibt es schon fertig in itertools, das braucht man nicht selbst zu schreiben. »Cameraset« und alle Variablennamen halten sich immer noch nicht an die üblichen Konventionen. Funktionen sollten nach einer Tätigkeit benannt sein. `Cams` wird gar nicht verwendet. Man iteriert direkt über Listen und baut sich neue, statt mit pop irgendwie die Liste zu verändern; das versteht nämlich niemand.

Nachdem ich raten konnte, was die unterschiedlichen Parameter bedeuten, kommt das dabei raus:
  1. def find_cameraset_with_only_valid_cameras(cameras_validity, set_size):
  2.     combs = list(combinations(range(len(cameras_validity), set_size))
  3.     for num, valid in enumerate(cameras_validity):
  4.         if not valid:
  5.             combs = [c for c in combs if c.count(num) == 0]
  6.     return combs

wobei man sich dann fragen muß, warum Du erst die Kombinationen aller Kameras erzeugst, um dann aus allen Kombinationen die ungültigen wieder zu entfernen und nicht gleich nur aus den Gültigen die Kombinationen erzeugst:
  1. def find_cameraset_with_only_valid_cameras(cameras_validity, set_size):
  2.     valid_cameras = [num for num, valid in enumerate(cameras_validity) if valid]
  3.     return list(combinations(valid_cameras, set_size))
drankaner
User
Beiträge: 13
Registriert: Freitag 27. Oktober 2017, 13:22

Re: Python + minGW

Beitragvon drankaner » Mittwoch 27. Dezember 2017, 13:34

Sirius3 hat geschrieben:@drankaner: wie sieht denn jetzt Dein Code aus, und welche Zeilen brauchen wie lange?

»combinations« gibt es schon fertig in itertools, das braucht man nicht selbst zu schreiben. »Cameraset« und alle Variablennamen halten sich immer noch nicht an die üblichen Konventionen. Funktionen sollten nach einer Tätigkeit benannt sein. `Cams` wird gar nicht verwendet. Man iteriert direkt über Listen und baut sich neue, statt mit pop irgendwie die Liste zu verändern; das versteht nämlich niemand.


Genau an dem Punkt habe ich angegriffen und den Quatsch mit "pop" wieder rausgeschmissen. Hier muss ich auch gestehen, dass die Funktion erstmal Blind geschrieben habe (Hauptsache es funktioniert).

  1. def find_valid_Cameraset(validCams,validCamsNo):
  2.       return list(combinations(validCams,validCamsNo))


Die Zeiten genau Untersuche ich jetzt nochmal genau. Bisher habe ich nur die Zeit für die gesamte Funktion.
8 Minuten für solveTriangulationLGS.py und 6-7 Minuten für calculatePointInCameraCoordSys.py.
drankaner
User
Beiträge: 13
Registriert: Freitag 27. Oktober 2017, 13:22

Re: Python + minGW

Beitragvon drankaner » Freitag 29. Dezember 2017, 10:02

Das die Variablen nicht der Konvention entsprechen, da stimme ich dir volkommen zu. Allerdings habe ich diese aus unserem tatsächlichen Programm das in C++ besteht (nicht von mir) übernommen und um später einfacher Sachen in dieses zu übernehmen habe diese bestehen lassen.

Nun ja mein
Sirius3 hat geschrieben:@drankaner: statt numpy.full nimmt man numpy.zeros. Welches Format haben denn local_cs_in_global_vector und local_tRefk_vector?
Ist x_iCamNo nicht einfach die Länge der Vektoren? Das braucht man dann nicht extra angeben.
Die ganzen asarray-Aufrufe sind in Deinem Fall überflüssig. Die Klammern bei den if und alle Strichpunkte sind das auch. Die einbuchstabigen Namen sind allesamt schlecht, weil sie nichts aussagen, für was sie stehen.

Die erste Hälfte ist vor allem mit dem `break` etwas seltsam, kann man aber bestimmt genauso zusammenfassen wie die zweite Hälfte, so dass es keine for-Schleifen mehr gibt:
  1.     s = x_pPoint3d - o
  2.     s2 = (s**2).sum(axis=1)
  3.     local = (r*s).sum(axis=1)
  4.     local = s2 - local**2 * r2r
  5.     maxsquaredist = local.max()
  6.     meansquaredist = local.mean()
  7.     return x_pPoint3d, maxsquaredist, meansquaredist


Ich habe den Code jetzt so angepasst.

local_cs_in_global_vector übergibt einen Vektor der so aussehen kann:
[array([ 0.06999708, 0.68877751, -0.72814772]), array([ 0.68212451, 0.08660196, -0.7334991 ])] (Je nach Anzahl der Kameras, kommt jeweils noch eine Zeile hinzu)

local_tRefk_vector übergibt einen solchen Vektor:
[[1.45608435, -220.028403, 264.029949], [-219.686839, 0.265470325, 264.474263]] (Je nach Anzahl der Kameras, kommt jeweils noch eine Zeile hinzu)

Und x_iCamNo die Anzahl der gültigen Kameras.

Ich habe auch schon einmal anngepasst das local_cs_in_global_vector und local_tRefk_vector jeweils im richtigen Format ankommen, sodass ich numpy.asarray nicht benötige, daraufhin bin ich aber direkt langsamer geworden und zwar deutlich. (Finde ich unlogisch, war aber tatsächlich so)

  1. def solverTriangulationLGS(local_cs_in_global_vector, local_tRefk_vector,x_iCamNo):
  2.  
  3.     a=numpy.zeros((3,3))
  4.     o=numpy.asarray(local_tRefk_vector)
  5.     r=numpy.asarray(local_cs_in_global_vector)
  6.  
  7.     a[0,0]=x_iCamNo
  8.     a[1,1]=x_iCamNo
  9.  
  10.     ###Vorbereitung 3D Punkt
  11.     #r2r = Ein einzelner Wert, je Kamera existiert einer!    
  12.     r2r=1/(r**2).sum(axis=1)
  13.     #local = Ein einzelner Wert, je Kamera existiert einer!
  14.     local=(r*o).sum(axis=1)
  15.     #r_2r = Ein 3er Vector, je Kamera existiert einer!
  16.     r_r2=(r.transpose()*r2r).transpose()
  17.     #b= ein 3er Vector
  18.     b = (o-(r_r2.transpose()*local).transpose()).sum(axis=0)
  19.     #a=eine 3x3 Matrix
  20.     a-=numpy.tensordot(r, r_r2, axes=[0,0])
  21.  
  22.     a[2][2] = x_iCamNo * 2 - a[0][0] - a[1][1];
  23.  
  24.    ###3D Punkt berechnen
  25.  
  26.     x_pPoint3d = numpy.matmul(numpy.linalg.inv(a),(b))
  27.  
  28.     ###Validierung des 3D Punkts
  29.     #s = Ein 3er Vector, je Kamera existiert einer!
  30.     s=x_pPoint3d-o
  31.     #s2 = Ein einzelner Wert, je Kamera existiert einer!
  32.     s2 = (s**2).sum(axis=1)
  33.     #local = Ein einzelner Wert, je Kamera existiert einer!
  34.     local = (r*s).sum(axis=1)
  35.     local = s2 - local*(local * r2r);
  36.  
  37.     maxsquaredist=local.max()
  38.     sumsquaredist=local.mean()
  39.  
  40.     return x_pPoint3d,maxsquaredist, sumsquaredist


@kbr: Folgendes kommt beim cProfiler raus (Ich habe mal nur die größten Punkte rausgenommen, aber anfangen kann ich damit nichts wirklich :/):

Code: Alles auswählen

1             252,125   252,125   1309,809   1309,809   trangulation_batch.py:17(triangulation_batch)               
35383040     81,419   0           81,419   0      {built-in   method   numpy.core.multiarray.array}         
24840580     79,705   0           79,705   0      {method   'reduce'   of   'numpy.ufunc'   objects}   
17639767     64,23   0           64,23   0      {built-in   method   numpy.core.multiarray.matmul}         
35486513     26,408   0           26,408   0      {built-in   method   numpy.core.multiarray.zeros}         
17743255     14,453   0           78,978   0      {method   'sum'   of   'numpy.ndarray'   objects}   
58992005     10,06   0           10,06   0      {built-in   method   time.time}         
10645953     9,351   0           9,351   0      {method   'reshape'   of   'numpy.ndarray'   objects}   
21291906     9,039   0           9,039   0      {method   'transpose'   of   'numpy.ndarray'   objects}   
3548656     8,684   0           8,684   0      {method   'astype'   of   'numpy.ndarray'   objects}   
3548651     7,597   0           7,597   0      {built-in   method   numpy.core.multiarray.dot}         
13086729     6,978   0           6,978   0      {built-in   method   numpy.core.multiarray.may_share_memory}         
16637016     4,4           0           4,4           0      {built-in   method   builtins.hasattr}         
28632953     3,764   0           3,764   0      {method   'append'   of   'list'   objects}   
3548651     2,383   0           51,048   0      {method   'mean'   of   'numpy.ndarray'   objects}   
7170593     2,278   0           2,283   0      {built-in   method   builtins.isinstance}         
3548723     2,261   0           2,261   0      {built-in   method   builtins.max}         
3548652     2,146   0           14,725   0      {method   'max'   of   'numpy.ndarray'   objects}   
3551510     1,268   0           1,268   0      {built-in   method   builtins.iter}         
3551908     1,169   0           1,169   0      {built-in   method   builtins.getattr}         
3548733     1,09   0           1,09           0      {built-in   method   builtins.min}         
3549617     1,039   0           1,04           0      {method   'get'   of   'dict'   objects}   
3548651     0,785   0           0,785   0      {method   '__array_prepare__'   of   'numpy.ndarray'   objects}   

Sirius3
User
Beiträge: 7067
Registriert: Sonntag 21. Oktober 2012, 17:20

Re: Python + minGW

Beitragvon Sirius3 » Freitag 29. Dezember 2017, 11:26

@drankaner: 35Mio Aufrufe dauern 81 Sekunden, die könnte man wahrscheinlich sparen, wenn man immer mit Numpy-Arrays arbeitet. Eine Liste von Arrays sieht daher komisch aus. Was dann aber nicht sein sollte, sind die vielen appends, die man nicht mit Numpy-Arrays machen sollte.
Dass Du solverTriangulationLGS 3,5Mio mal aufrufst, hast Du aber nicht gesagt, und in Deinem Profiler-Output fehlen auch alle Zeilen mit Deinen Python-Funktionen. Also bei dem Stückwerk und den ganzen Dingen, die Du verheimlichst, kann man Dir wirklich nicht helfen.

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder