Autor Beitrag
kat1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 40

Win XP
D6 EntPr
BeitragVerfasst: Mo 07.07.03 18:34 
Hallo,

mal wieder ein kleines Problem mit der Behandlung von array's. Angenommen ich habe:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
A:array of array of extended;
b:array of extended;

{...}

SetLength(A,n,n);
SetLength(b,n);

{...}

Decomposition(A(0..j,0..j),b(0..j));

Das heißt also, ich habe ein großes zweidimensionales array und ein eindimensionales, die während meiner Prozedur mit Werten gefüllt werden. Ich möchte aber dann eine Funktion eben nur auf eine Untermenge dieser arrays anwenden. Ist so etwas in Delphi überhaupt möglich?

Scheint ja irgendwie mit Copy zu funktionieren, aber so richtig dahinter gekommen bin ich noch nicht

Moderiert von user profile iconTino: Delphi-Tags hinzugefügt.

_________________
Mfg Uwe
Es ist eine Unsitte der Menschen, sich an alles zu gewöhnen.
worm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 135


D6 Prof
BeitragVerfasst: Mo 07.07.03 22:26 
Ja, das geht mit Copy, und in bestimmten Fällen (wenn Du nur den Anfang brauchst) auch mit Slice... aber was genau willst du überhaupt? Sonst können wir auch nicht sagen, wie du Copy aufrufen musst :shock:.

_________________
In the beginning, the universe was created. This has made a lot of people very angry, and is generally considered to have been a bad move.
kat1 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 40

Win XP
D6 EntPr
BeitragVerfasst: Mo 07.07.03 23:43 
Danke erstmal für die Antwort,

ja es schaut für mich so aus, dass ich nur den Befehl slice bräuchte, aber mal kurz zur Erklärung. Ist ein übliches Problem der Mathematik. Lösung linearer Gleichungssysteme. Dabei ist A eine n x n-Matrix, also in diesem Fall ein zweidimensionales Array, die die Koeffizienten enthält. b ist der Lösungsvektor, also n x 1 und damit ein array. Die genannte Prozedur (Decomposition) löst das Gleichungssystem durch Invertierung dieser Matrix.

Ist aber für große Matrizen A nicht unbedingt der schnellste Weg. Deswegen habe ich einen anderen Algorithmus verwendet, indem ich halt die Lösung eines Gleichungssystems, das kleiner als die gesamte Matrix ist, verwenden muss. Das heißt in diesem Falle konkret brauche ich nur den Sub-array der Matrix A und zwar von jeweils (0..j) in jeder Dimension und selbstverständlich auch nur einen Teil des Vektors b (0..j). Da ich dabei immer mit dem Element Null anfange, müsste das auch mit Slice funktionieren.

Meine Frage ist nun. Bringen mir die Befehle

ausblenden Delphi-Quelltext
1:
2:
slice(A,j+1);
slice(b,j+1);


die gewünschten arrays oder muss ich das anders formulieren. Das frage ich mich halt auch wegen des mehrdimensionalen arrays A, da sich die Online-Hilfe dazu leider nicht sehr ergiebig zeigt.

_________________
Mfg Uwe
Es ist eine Unsitte der Menschen, sich an alles zu gewöhnen.
worm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 135


D6 Prof
BeitragVerfasst: Di 08.07.03 01:50 
Für das eindimensionale Array / den Vektor b ist der Aufruf schon richtig.
Bei mehrdimensionalen Arrays kannst du Slice so nicht verwenden.
So, habe das mal selbst ausprobiert, ging leider nicht so einfach, musste eine eigene Funktion schreiben, von der ich nur hoffen kann, dass sie schnell ist :)
ausblenden Delphi-Quelltext
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:
27:
28:
type
  TVector = array of Extended;
  TMatrix = array of TVector;

var
  A: TMatrix;

function MatrixSlice(const AMatrix: TMatrix; Size: Integer): TMatrix;
var i: Integer;
begin
  SetLength(Result, Size);
  for i := 0 to Size-1 do
    Result[i] := Copy(AMatrix[i], 0, Size);  //Slice mag TMatrix nicht :(
end;

procedure Test(A: TMatrix);
begin
  ShowMessageFmt('Größe der Matrix: %dx%d', [High(A)+1, High(A[0])+1]);
end;


begin
  //Größe der Matrix auf 3x3 festlegen
  SetLength(A, 33);
  //Test einmal mit der 3x3, und einmal mit der "gesliceten" 2x2-Matrix
  Test(A);
  Test(MatrixSlice(A, 2));
end;

_________________
In the beginning, the universe was created. This has made a lot of people very angry, and is generally considered to have been a bad move.


Zuletzt bearbeitet von worm am Di 08.07.03 15:36, insgesamt 1-mal bearbeitet
kat1 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 40

Win XP
D6 EntPr
BeitragVerfasst: Di 08.07.03 09:44 
Vielen Dank,

ja, das scheint zu funktionieren. Hatte allerdings mittlerweile eine andere Lösung gefunden, indem ich der Prozedur noch die jeweils benötigte Größe als Wert übergebe und damit dann die Schleifen steuere. Hat zwar den Nachteil, dass man halt das komplette array übergibt, aber wer damit leben kann. :)

Deine Version ist natürlich eleganter.

_________________
Mfg Uwe
Es ist eine Unsitte der Menschen, sich an alles zu gewöhnen.
worm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 135


D6 Prof
BeitragVerfasst: Di 08.07.03 13:56 
Das Übergeben des kompletten Arrays ist glaube ich sogar besser, solange Du den Parameter als const deklarierst. Also z.B. procedure Test(const A: TMatrix); Dann wird nämlich nicht richtig das ganze Array übergeben, sondern ein Verweis auf das schon existierende Array. So gesehen ist das dann sogar besser, als noch ein neues, kleineres Array zu erstellen (und schneller wohl auch). Also bleib lieber bei deiner Version!

_________________
In the beginning, the universe was created. This has made a lot of people very angry, and is generally considered to have been a bad move.
kat1 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 40

Win XP
D6 EntPr
BeitragVerfasst: Di 08.07.03 14:02 
Ja, aber genau das funktioniert nicht, weil ich doch bei einer Dekomposition die Matrix zerlege und dabei auch die jeweiligen Elemente verändere und genau das geht nicht bei einem const Parameter. Ich habe es jetzt folgendermaßen gemacht:
ausblenden Delphi-Quelltext
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:
function LU_Decomposition(CoMatrix:TComplexMatrix;ResultVector:TComplexVector;
                          ResDimension:integer):TComplexVector;
const
   tiny=1.0e-20;
var
   k,j,imax,i,ii,ip,n: integer;
   dum,big: extended;
   indx:array of integer;
   vv: array of extended;
   sum,change,dum2:TComplexCart;
   Vector:TComplexVector;
   Matrix:TComplexMatrix;
begin
        //Initialization

  n:=ResDimension;
  SetLength(vv,n);
  SetLength(indx,n);
  SetLength(Matrix,n,n);
  SetLength(Vector,n);

        //Creation of the Sub-Matrix and the Sub-Vector
        
Vector:=Copy(ResultVector,0,n);
  for i:=0 to n-1 do
    Matrix[i]:=Copy(CoMatrix[i],0,n);


Funzt einwandfrei, danke! :wink:

Ist übrigens verhältnismäßig schnell.

_________________
Mfg Uwe
Es ist eine Unsitte der Menschen, sich an alles zu gewöhnen.