[gelöst] sigsev bei Schleife

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Hartkern
Beiträge: 69
Registriert: Sa 5. Dez 2015, 20:03
OS, Lazarus, FPC: Win10 IDE 1.6
CPU-Target: 64Bit
Wohnort: Leipzig

[gelöst] sigsev bei Schleife

Beitrag von Hartkern »

Hallo,
ich probiere gerade das Jacobi Iterationsverfahren (N Unbekannte mit N Gleichung) umzusetzen... beim ausfiltern der Diagonalen bekomme ich unerklärlicher Weise einn SigSev, also irgendwie kann auf irgendwas nicht zugegriffen werden... :shock:

Code: Alles auswählen

unit Main;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, Grids;
 
type
  TDet = array of array of real; //Determiantn Matrix
 
  { TForm1 }
type
  TForm1 = class(TForm)
    Button1: TButton;
 
    Button2: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Memo1: TMemo;
    Panel1: TPanel;
    SGWerte: TStringGrid;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure test;
    procedure jacobi(WerteMatrix: TDet; bMatrix :array of real);
  private
    { private declarations }
    AnzN: integer;     //Anzahl der gesuchten Variablen
    aWerte : TDet; // 2d Array der Determinanten
    aErgebnis : array of real; // ergebnis b matrix
 
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
Var
  i:Integer;
begin
  AnzN := StrToInt(Edit1.Text);
  //Label für Eingabehilfe anzeigen
  label2.Visible:=true;
  label2.Enabled:=true;
  //Stringrid vorbereiten
  SGWerte.ColCount:=AnzN+2;
  SGWerte.RowCount:=AnzN+1;
  SGWerte.Cells[1,0]:='B = ';
  For I:=2 to AnzN+1 do
      begin
        SGWerte.Cells[I,0]:='ax'+IntToStr(I-1);
      end;
  For I:=1 to AnzN do
      begin
        SGWerte.Cells[0,I]:='x'+IntToStr(I);
      end;
  SGWerte.Visible:=true;
  //werte button aktivieren
  button2.Enabled:=true;
  memo1.Lines.Clear;
end;
 
procedure TForm1.Button2Click(Sender: TObject);
Var
  i,j : Integer; //Zählervariablen für Array aWerte befüllen
begin
  // ergebnismatrix b befüllen
  setlength(aErgebnis,AnzN);
  For I:=0 to AnzN-1 do
      begin
         if SGWerte.Cells[1,i+1] = '' then SGWerte.Cells[1,i+1]:='0';    //wenn nix in der Zelle dann halt Wert 0
         aErgebnis[i]:=StrToFloat(SGWerte.Cells[1,i+1]);
      end;
  // Werte in 2D Array einlesen
  setlength(aWerte,AnzN,AnzN);
  For I:=0 to AnzN-1 do
      begin
        For J:=0 to AnzN-1 do
            begin
              if SGWerte.Cells[i+2,j+1] = '' then SGWerte.Cells[i+2,j+1] :='0';    //wenn nix in der Zelle dann halt Wert 0
              aWerte[i,j]:=StrToFloat(SGWerte.Cells[i+2,j+1]);
            end;
      end;
  //Jacobi ITERATION starten
  Jacobi(aWerte,aErgebnis);
end;
 
procedure TForm1.test;
Var
  i,j : Integer; //Zählervariablen
begin
 
end;
 
procedure TForm1.jacobi(WerteMatrix: TDet; bMatrix: array of real);
var
  aDiagonalwerte : Array of real;
  i : integer;
  j : integer;
  aBerechnung : TDet; //TDet = array of array of real
begin
  //Berechnungsarray erzeugen
  (*  0 =  1/d, b, +-x2, +-x3...xn
      1 =  1/d, b, +-x1, +-x3...xn
      2 =  1/d, b, +-x1, +-x2, x4..xn *)
  //2 feste Variablen + Unbekannte minus 1
  setlength(aBerechnung,length(bMatrix),(2+AnzN-1));
 
  //Werte x1[0,0], x2[1,1]....xn[n-1,-n-1] der Koeffzientenmatrix in Diagonale einlesen
  Setlength(aDiagonalwerte,length(bMatrix));
  For i:=0 to high(aDiagonalwerte) do
      begin
        aDiagonalwerte[i]:=WerteMatrix[i,i];
      end;
 
  //DiagonelenMatrixwerte an erste Stelle der Berechnungsmatrix setzen, dabei 1/n rechen
  For I:=0 to high(aDiagonalwerte) do
      begin
        aBerechnung[i,0]:=1/(aDiagonalwerte[i]);
      end;
  //Werte aus BMatrix an die 2. Zeile des Berechnungsarrays setzen
  For I:=0 to high(bMatrix) do
      begin
        aBerechnung[i,1]:=bMatrix[i];
      end;
 
  //sämtliche Werte aus Wertematrix in die Berechnungsmatrix ab Position i,2....n einlesen
  //dabei Umkehrung der Vorzeichen (Umstellung der Formel)
  //ausfiltern der Werte x1,x2..xn aus der Diagonalenmatrix
  (*  0 =  1/d_0, b_0, +-x2_0, +-x3_0
      1 =  1/d_1, b_1, +-x1_1, +-x3_1
      2 =  1/d_2, b_2, +-x1_2, +-x2_2,
      n = *)
 i:=-1;
  repeat
    inc(i);
    J:=-1;
      repeat
         inc(j);
         IF WerteMatrix[i,j] = aDiagonalwerte[i]  // <--hier sollen die x1 in 1 Zeile ff. rausgefiltert werden..SigSev
         then
             begin
               inc(J);
             end
         else
             begin
               aBerechnung[i,j+2]:=(-1*Wertematrix[i,j]);
             end;
      until  j = length(bMatrix)-1;
  until i = length(bMatrix)-1;
 
 
 
 
 
    //test
     For I:=0 to high(aBerechnung) do
      begin
        For J:=0 to high(aBerechnung) do
            begin
              Memo1.Lines.Add(FloatToStr(aBerechnung[i,j]));
            end;
      end;
 
  //Iteration starten, Timer starten
 
 
  //Ausgeben der gefundenen x1, x2....xn, benötigte Zeit ausgeben
end;
 
 
end.   
Zuletzt geändert von Hartkern am Fr 10. Jun 2016, 17:47, insgesamt 1-mal geändert.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: sigsev bei Schleife

Beitrag von Michl »

Ich nehme mal an, du hast dein Projekt mit Debuginformationen kompiliert?!

Welche Werte haben diese Variablen?:

Code: Alles auswählen

WerteMatrix
i
j
aDiagonalwerte
(Nach dem SIGSEGV einfach mit der Maus über dem Bezeichner stehen bleiben oder die Variablen mit <Strg> + <F5> zu den überwachten Ausdrücken hinzufügen)

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antworten