Zeiger für symetrische Matrizen verwenden (Ansi C)
-
pluseins schrieb:
Warum
long double N[2][2]
bei 3x3?Hi, weil mir die abschließende Größe unbekannt ist und ich "keine Einschränkungen" nach oben haben will.
Ich lese Koordinatendateien mit ca 600 - 800MB ein. Die einzelnen Matrixelemente sind Quadratesummen. Dadurch wachsen die Elemente sehr schnell an.
-
Kann ich nicht z. B. :
N[1][2] = *N[2][1]
oder ähnliches verwenden damit er gerade die Adressen übernimmt?
-
darkfate schrieb:
Frage: Könnte man nicht RAM sparen und mit Zeigern arbeiten?
nee, wenn du die ganze matrix im speicher brauchst, dann brauchste auch RAM, z.b. mit malloc:
// matrix anlegen, DIM ist breite und höhe double *squarematrix = malloc (DIM * DIM * sizeof(double)); ... // lesen von wert, spalte y, zeile x double number = squarematrix[y*DIM+x]; ... // schreiben wie gehabt squarematrix[y*DIM+x] = ...;
-
;fricky schrieb:
nee, wenn du die ganze matrix im speicher brauchst, dann brauchste auch RAM, z.b. mit malloc:
Nun bin ich ein wenig verwirrt...
Wenn ich mit long double N[3][3] = {0} intialisiere wird sie nicht komplett in den Speicher geladen wenn ich sie nachher mit echten Werten betanke?
Außerdem will ich ja nicht die ganze Matrix im Speicher haben sondern möchte dass:
N[0][1] auf N[1][0] zeigt.
N[1][2] auf N[2][1] zeigt. usw...mir geht es jetzt auch nicht unbedingt um diese 3x3 Matrix sondern um die Technik.
Ich habe zum Beispiel eine A-Matrix mit knapp einem GB long double koordinaten.
Dann habe ich eine Transponierte A-Matrix die praktisch nichts anderes macht als redundante Daten im Speicher anzulegen und ich wollte es irgendwie mit Zeigern lösen.Im Moment sieht es noch so aus:
for( i=0 ; i <= pcount ; i++ ) { A[0][i] = x[i] - meanx; A[1][i] = y[i] - meany; A[2][i] = z[i] - meanz; [b]At[i][0] = A[0][i];[/b] [b]At[i][1] = A[1][i];[/b] [b]At[i][2] = A[2][i];[/b] N[0][0] += A[0][i] * A[0][i]; N[1][1] += A[1][i] * A[1][i]; N[2][2] += A[2][i] * A[2][i]; N[0][1] += A[0][i] * A[1][i]; N[0][2] += A[0][i] * A[2][i]; N[1][2] += A[1][i] * A[2][i]; } [b]N[1][0] = N[0][1]; N[2][0] = N[0][2]; N[2][1] = N[1][2];[/b]
Ich würde mir gern den redundanten Platz sparen. Macht es vielleicht der Compiler automatisch? Wie kann ich das überprüfen?
Danke für die Antworten...
-
darkfate schrieb:
Wenn ich mit long double N[3][3] = {0} intialisiere wird sie nicht komplett in den Speicher geladen wenn ich sie nachher mit echten Werten betanke?
der speicher wird aber trotzdem reserviert. in dem fall 3*3*sizeof(typ).
darkfate schrieb:
Außerdem will ich ja nicht die ganze Matrix im Speicher haben sondern möchte dass:
N[0][1] auf N[1][0] zeigt.
N[1][2] auf N[2][1] zeigt. usw...wenn du den speicher mit malloc anlegst (wie ich oben angedeutet habe), dann kannste z.b. mit matrix[mdim+n]* auf das original und mit matrix[ndim+m]* (transponierte ansicht, zeilen und spalten vertauscht) zugreifen, brauchst also nix doppelt.
-
;fricky schrieb:
wenn du den speicher mit malloc anlegst (wie ich oben angedeutet habe), dann kannste z.b. mit matrix[mdim+n]* auf das original und mit matrix[ndim+m]* (transponierte ansicht, zeilen und spalten vertauscht) zugreifen, brauchst also nix doppelt.
Danke schonmal für deine Antwort.
Bei mir kommt so langsam die Einsicht dass deine Option super ist. Ich hätte schon in der ersten Nachricht darüber nachdenken können.
Nun habe ich dennoch ein Problem dass ich die künftige Algorithmik komplett umgeschreiben muss. Außerdem erinnert N[zeile][spalte] an den Mathematikunterricht
Verweisende Zeiger innerhalb eines Arrays würde nicht funktionieren ohne dass Speicher reserviert wird?
-
darkfate schrieb:
Außerdem erinnert N[zeile][spalte] an den Mathematikunterricht
mach doch funktionen daraus:
double N (int zeile, int spalte) // original { return matrix (spalte*DIM+zeile); } ... double NT (int zeile, int spalte) // transposed view { return matrix (zeile*DIM+spalte); }
darkfate schrieb:
Verweisende Zeiger innerhalb eines Arrays würde nicht funktionieren ohne dass Speicher reserviert wird?
doch. zeiger brauchen nur speicher für sich selber (sizeof(*typ)), also ziemlich wenig. bei arrays, z.b. double N[2][3][4] wird z.b. 2*3*4*sizeof(double) speicher benötigt.
merke: arrays sind keine zeiger sind umgekehrt auch nicht.
-
;fricky schrieb:
mach doch funktionen daraus:
Die Anwendung ist sehr performancekritisch... Funktionen benötigen nur unnötig CPU Ticks...
-
darkfate schrieb:
;fricky schrieb:
mach doch funktionen daraus:
Die Anwendung ist sehr performancekritisch... Funktionen benötigen nur unnötig CPU Ticks...
dann gehts auch mit makros.
-
dann gehts auch mit makros.
Wie sieht's eigentlich mit inlining aus? Da müsste sich doch langsam etwas durchsetzen, oder?