Está en la página 1de 18

unit NEWTONparaSISTEMAS2;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls,ParseExpr, Spin, Buttons;

type

TString=Array of string;

Totros=Class

xo:double;

VarResultado:string;

function ExpressionParser(Equation:string;Variables:string;Values:string):double;

function Occurs(const str: string; const substr: string): integer;

function DelphiSplit(const str: string;const separator: string): TString;

procedure solverecua(Fx:string;listvar:string;listval:string);

function Resultados():string;

end;

TEditArray = array of TEdit;

T2DEditArray = array of TEditArray;

TLabelArray =array of Tlabel;

T2DLabelArray=array of TLabelArray;

TFloatArray = array of string;

T2DFloatArray = array of TFloatArray;

TMatrixSize = Packed Record


X: Integer;

Y: Integer;

End;

TForm1 = class(TForm)

SpinEdit1: TSpinEdit;

Memo1: TMemo;

Label1: TLabel;

limpiar: TBitBtn;

salir: TBitBtn;

itera: TLabel;

tdelta: TEdit;

Label2: TLabel;

calcular: TBitBtn;

procedure creaedits(AOrder : integer);

procedure DestroyEdits;

procedure CalcularClick(Sender: TObject);

procedure SpinEdit1Change(Sender: TObject);

procedure FormCreate(Sender: TObject);

procedure limpiarClick(Sender: TObject);

procedure salirClick(Sender: TObject);

private

{ Private declarations }

////////////////////////////////BSRA////////////////////////////////////////////

public

{ Public declarations }

LeftEdits : T2DEditArray;

RightEdits : TEditArray;

LeftLabels : T2DlabelArray;

RightLabels : TLabelArray;
ResultEdits : TEditArray;

Order : integer;

end;

var

Form1: TForm1;

detJ,detM,trza,zo,yo,xo:double;

vallistT,varlist,vallist:string;

labvar:array[1..10] of string ;

difval,res,VB,Mvalt, mval,mtfun:array [1..10] of double;

Valdet:array[1..10]of double;

A,Bb,C,B,MjacTp,MjacT,mvaldelta, Mjacob:array [1..10,1..10] of double;

VarEcuacion:string;

variablelist,valorlist:string;

n,pibe1:integer;

delta:real;

bo:integer;

//const

// delta=0.0000001;

implementation

{$R *.dfm}

///////////////////////////////////////////////////////////////////////////////

// FUNCIONES DE LECTURA DE 'CADENAS' -->> ECUACIONES EVALUABLES

function Totros.Occurs(const str: string; const substr: string): integer;


// Devuelve la cantidad de veces que una subcadena está en una cadena

var

p, q: PChar;

n: integer;

begin

Result := 0;

n := Length(substr);

if n = 0 then exit;

q := PChar(Pointer(substr));

p := PChar(Pointer(str));

while p <> nil do begin

p := StrPos(p, q);

if p <> nil then begin

inc(Result);

inc(p, n);

end;

end;

end;

function Totros.DelphiSplit(const str: string;const separator: string): TString;

// Devuelve un arreglo con las partes de "str" separadas por

// "separator"

var

i, n: integer;

p, q, s: PChar;

begin

SetLength(Result, Occurs(str, separator)+1);

p := PChar(str);

s := PChar(separator);
n := Length(separator);

i := 0;

repeat

q := StrPos(p, s);

if q = nil then q := StrScan(p, #0);

SetString(Result[i], p, q - p);

p := q + n;

inc(i);

until q^ = #0;

end;

function Totros.ExpressionParser(Equation:string;Variables:string;Values:string):double;

var

MyParser:TExpressionParser;

MyParserEquation:integer;

ArrayVariables:TString;

ArrayStringValues:TString;

ArrayValues:array of double;

i:integer;

begin

ArrayVariables:=DelphiSplit(Variables,','); // LISTA DE VARIABLES SEPARADOS POR COMA (,)

ArrayStringValues:=DelphiSplit(Values,';'); // LISTA DE VALORES INICIALES SEPARADOS POR


PTOCOMA (;)

SetLength(ArrayValues,length(ArrayStringValues));

for i:=0 to length(ArrayStringValues)-1 do

begin

ArrayValues[i]:=StrToFloat(ArrayStringValues[i]);

end;
MyParser := TCstyleParser.Create;

TCStyleParser(MyParser).CStyle:=False;

//MyParser.DecimSeparator:=',';

for i:=0 to length(ArrayVariables)-1 do

begin

MyParser.DefineVariable(ArrayVariables[i],@ArrayValues[i])

end;

MyParser.Optimize:=true;

MyParserEquation:=MyParser.AddExpression(Equation);

Result:= StrToFloat(MyParser.AsString[MyParserEquation]);

end;

///////////////////////////////////////////////////////////////////////////////

// PROCEDIMIENTOS PARA EVALUACION DE ECUACIONES

procedure Totros.solverecua(Fx:string;listvar:string; listval:string);

var sol:double;

begin

sol:=ExpressionParser(Fx,listvar,listval);

VarResultado:=floattostr(sol);

end;

function Totros.Resultados():string;

begin

Result:=VarResultado;

end;

///////////////////////////////////////////////////////////////////////////////

/// CREA FORMULARIO

procedure TForm1.creaedits(AOrder : integer);

Var

LCol, LRow, Lx, Ly : integer;


begin

{coordenadas iniciales de los Tedits}

Lx := 70;

Ly := 165;

SetLength(LeftEdits, AOrder);

SetLength(RightEdits, AOrder);

SetLength(Leftlabels, AOrder);

SetLength(Rightlabels, AOrder);

for LRow := 0 to AOrder - 1 do

begin

// crea la columna de ecuaciones

SetLength(LeftEdits[LRow], AOrder);

SetLength(Leftlabels[LRow], AOrder);

for LCol := 0 to 0 do

begin

LeftEdits[LRow][lcol] := TEdit.Create(Self);

with LeftEdits[LRow][lcol] do

begin

parent:=form1;

Left := Lx;

Top := Ly;

Height := 20;

Width := 200;

Text := '';

end;

Leftlabels[LRow][lcol] := Tlabel.Create(Self);

with Leftlabels[LRow][lcol] do

begin
parent:=form1;

Left := Lx-45;

Top := Ly+6;

Font.Style:= [fsBold];

caption := 'Ecu.'+inttostr(lrow+1);

end;

end;

// crea la columna de valores iniciales

RightEdits[LRow] := TEdit.Create(Self);

with RightEdits[LRow] do

begin

parent:=form1;

Left := 325;

Top := Ly;

Height := 20;

Width := 30;

Text := '';

end;

Rightlabels[LRow] := Tlabel.Create(Self);

with Rightlabels[LRow] do

begin

parent:=form1;

Left := 325-30;

Top := Ly+3;

Font.Style:= [fsBold];

caption:= 'X= '+inttostr(lrow+1);

end;

Lx := 70;
Inc(Ly, 22);

end;

end;

procedure TForm1.DestroyEdits;

Var

LCol, LRow : integer;

begin

for LRow := 0 to High(LeftEdits) do begin

// destruye lado izquierdo de TEdit

for LCol := 0 to High(LeftEdits[0]) do

begin

LeftEdits[LRow][LCol].Free;

Leftlabels[LRow][LCol].Free;

end;

// destruye lado derecho de TEdit

RightEdits[LRow].Free;

RightLabels[LRow].Free;

end;

if length(ResultEdits) > 0 then begin

// destruye resultados

for LCol := 0 to High(ResultEdits) do ResultEdits[LCol].Free;

SetLength(ResultEdits, 0);

end;

end;

//////////////////////////////////////////////////////////////////////////////

// PROCEDIMIENTOS UTILES
procedure saliresultados;

var ik:integer;

begin

form1.Memo1.Lines.Add('Nº iter.='+inttostr(pibe1));

for ik:=1 to n do

form1.Memo1.Lines.Add('X.'+inttostr(ik)+'= '+floattostr(mval[ik]));

form1.Memo1.Lines.Add('_________________________ ');

end;

//linea1:='(_______________________)';

//Memo1.items.add(linea11);

procedure detjac; //DETERMINANTE DEL JACOBIANO

var ii,ji,li,ki:integer;

begin

B:=Mjacob;

A:=mjacob;

trza:=0;

for ii:=1 to n do

trza:=trza+B[ii,ii];

VB[1]:=-1*trza;

bb:=b;

for ii:=1 to n do

Bb[ii,ii]:=B[ii,ii]+VB[1];

for ki:=2 to n do

begin begin

for ii:=1 to n do begin


for ji:=1 to n do

begin

C[ii,ji]:=0;

for li:=1 to n do

C[ii,ji]:=C[ii,ji]+A[ii,li]*Bb[li,ji] ;

end; end; end;

B:=C;

trza:=0;

for ii:=1 to n do

trza:=trza+B[ii,ii];

VB[ki]:=-1*trza/ki;

for ii:=1 to n do

Bb[ii,ii]:=B[ii,ii]+VB[ki];

end;

detJ:=Vb[n];

end;

procedure detMAT; // DETERMINANTE DEL NUMERADOR INCOGNITA

var ij,jj,lj,kj:integer;

begin

B:=MjacTp;

A:=mjacTp;

trza:=0;

for ij:=1 to n do

trza:=trza+B[ij,ij];

VB[1]:=-1*trza;

bb:=b;

for ij:=1 to n do

Bb[ij,ij]:=B[ij,ij]+VB[1];
for kj:=2 to n do

begin begin

for ij:=1 to n do begin

for jj:=1 to n do

begin

C[ij,jj]:=0;

for lj:=1 to n do

C[ij,jj]:=C[ij,jj]+A[ij,lj]*Bb[lj,jj] ;

end; end; end;

B:=C;

trza:=0;

for ij:=1 to n do

trza:=trza+B[ij,ij];

VB[kj]:=-1*trza/kj;

for ij:=1 to n do

Bb[ij,ij]:=B[ij,ij]+VB[kj];

end;

detM:=Vb[n];

end;

////////////////////////////////////////////////////////////////////////////////

// INICIO CALCULOS

procedure TForm1.CalcularClick(Sender: TObject);

label label1,label2;

var

otro:Totros;

LLeftSide : T2DFloatArray;

LRightSide: TFloatArray;

LRow, LCol : integer;


m,l,k,i,j:integer;

begin

val(tdelta.Text,delta,bo);

n:= strtoint(spinedit1.Text);

case n of

2: varlist:='x,y';

3: varlist:='x,y,z';

4: varlist:='x,y,z,l';

5: varlist:='x,y,z,l,m';

end;

///////////////////////////////////////////////////////////////////////////////

// transfiere datos de edits a arrays de cadenas

vallist:=Rightedits[0].Text;

SetLength(LLeftSide, Order);

SetLength(LRightSide, Order);

for LRow := 0 to Order-1 do

begin

SetLength(LLeftSide[LRow], Order);

for LCol := 0 to 0 do

begin

// if LeftEdits[LRow][LCol].Text = '' then Exit;

LLeftSide[LRow][LCol] := LeftEdits[LRow][LCol].Text;

end;
if RightEdits[LRow].Text = '' then Exit;

LRightSide[LRow]:= RightEdits[LRow].Text;

vallist:=vallist+';'+Rightedits[Lrow+1].Text;

end;

///////////////////////////////////////////////////////////////////////////////

//EVALUACION DE ECUACIONES INICIALES CON VALORES INICIALES

pibe1:=0;

otro:=totros.Create;

for i:=1 to n do mval[i]:=strtofloat(Rightedits[i-1].Text);

label1:

for i:=1 to n do

begin

varecuacion:= LeftEdits[i-1][0].Text;

otro.solverecua(varecuacion, varlist, vallist);

mtfun[i]:=strtofloat(otro.Resultados()) ;

Mvalt[i]:=mval[i];

end;

vallistT:=vallist;

////////////////////////////////////////////////////////////////////////////////

//MATRIZ DE DERIVADAS PARCIALES}

for i:=1 to n do

begin

for j:=1 to n do

begin

if j=i then

mvaldelta[i,j]:=mvalt[j]+delta

else
mvaldelta[i,j]:=mvalt[j];

end;

end;

for i:=1 to n do

begin

for j:=1 to n do

begin

varecuacion:= LeftEdits[i-1][0].Text;

vallist:=floattostr(mvaldelta[j,1]);

for k:=1 to n-1 do

vallist:=vallist+';'+floattostr(mvaldelta[j,k+1]);

otro.solverecua(varecuacion, varlist, vallist);

MJacob[i,j]:=(strtofloat(otro.Resultados())-mtfun[i])/delta ;

pibe1:=pibe1+1;

end;

end;

MjacT:=MJacob; //Matrices temporales de apoyo

MjacTp:=MjacT; //Matrices temporales de apoyo

////////////////////////////////////////////////////////////////////

detjac; //DETERMINANTE DEL JACOBIANO

////////////////////////////////////////////////////////////////////

//DETERMINANTE DEL NUMERADOR

for i:=1 to n do

begin
MjacTp:=mjact;

for j:=1 to n do

MjacTp[j,i]:=-1*mtfun[j];

detMat;

Valdet[i]:=detM;

end;

///////////////////////////////////////////////////////////////////////////////

//EVALUA NEWTON PARA SISTEMAS

k:=0;

for i:=1 to n do

begin

res[i]:=mval[i]+(valdet[i]/detJ);

difval[i]:= mval[i]-res[i];

if abs(difval[i])>= delta then

begin

mval[i]:=res[i];

k:=k+1;

end;

end;

if k=0 then goto label2;

///////////////////////////////////////////////////////////////////////////////

//ITERA NEWTON PARA SISTEMAS

vallist:=floattostr(mval[1]);

for k:=1 to n-1 do


vallist:=vallist+';'+floattostr(mval[k+1]);

goto label1;

///////////////////////////////////////////////////////////////////////////////

// MUESTRA RESULTADOS

label2:

saliresultados;

itera.Caption:='Nº DE ITER = '+inttostr(pibe1);

end;

procedure TForm1.SpinEdit1Change(Sender: TObject);

var mn:integer;

begin

memo1.Clear;

mn:=strtoint(spinedit1.Text);

DestroyEdits;

creaedits(mn);

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

memo1.Clear;

Order := strtoint(spinedit1.Text);

CreaEdits(Order);

end;
procedure TForm1.limpiarClick(Sender: TObject);

begin

memo1.Clear;

itera.Caption:='';

end;

procedure TForm1.salirClick(Sender: TObject);

begin

close;

end;

end.

También podría gustarte