Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Neuen Beitrag zur Code-Library hinzufügen (https://www.delphipraxis.net/33-neuen-beitrag-zur-code-library-hinzufuegen/)
-   -   Delphi Potenzreihen: Horner (https://www.delphipraxis.net/136257-potenzreihen-horner.html)

Dipl Phys Ernst Winter 26. Jun 2009 15:03


Potenzreihen: Horner
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zur Berechnung von Potentzreihen und iher Ableitung benutzt man das Schema nach Horner. Ich habe dafür zwei Fubnktionen in einer Unit bereitgestellt:
Delphi-Quellcode:
// Funktionsmwert einer Potenzreihe mit
//   n    Rang
//   c[i] i = 0..n Koefiziendenvektor
//   x    Argument
function HornerFkt(const n: byte; const c: array of extended;
                   const x: extended): extended;
var
  i: integer;
begin
  Result := c[n];                                             // y nach Horner
  for i:= n-1 downto 0 do Result:= Result*x + c[i];           // berechnen,
end;

// Wert der Ableitung einer Potenzreihe mit
//   n    Rang
//   c[i] i = 0..n Koefiziendenvektor
//   x    Argument
function HornerAbl(const n: byte; const c: array of extended;
                     const x: extended): extended;
var
  i: integer;
begin
  if n=0 then Result:= 0 else if n=1 then Result:= c[1]
  else begin
    Result:= n*c[n]*x;
    for i:= n-1 downto 2 do Result:= (Result + i*c[i])*x;
    Result:= Result + c[1] end
end;

jfheins 27. Jun 2009 00:01

Re: Potenzreihen: Horner
 
Sieht ganz nett aus.

Was ich aber noch ändern würde ist der Parameter n. Den kann man ja wohl ersetzen durch high(c) oder nicht?

Dipl Phys Ernst Winter 27. Jun 2009 08:20

Re: Potenzreihen: Horner
 
"jfheins"

Zitat:

Was ich aber noch ändern würde ist der Parameter n. Den kann man ja wohl ersetzen durch high(c) oder nicht?
Nein! high(c) würde maxRang, die dimensionierte Länge des Arrays zurückgeben, während der Rang der Potenzreihe benötigt wird.

jfheins 28. Jun 2009 12:31

Re: Potenzreihen: Horner
 
Ich denke, man sollte die Parameter seperat erklären, da sie ja nicht "sprechend" sind.

Also z.B.:
Delphi-Quellcode:
// HornerFkt - Berechnet den Funktionswert eines Polynoms
// n: Grad des Polynoms
// c: Koeffizienten des Polynoms (aufsteigend)
// x: Argument
// Rückgabe: Funktionswert an der Stelle x
function HornerFkt(const n: integer; const c: array of extended;
                   const x: extended): extended;
var
  i: integer;
begin
  Result := c[n];                                             // y nach Horner
  for i:= n-1 downto 0 do Result:= Result*x + c[i];           // berechnen,
end;

// HornerAbl - Berechnet die Ableitung eines Polynoms
// n: Grad des Polynoms
// c: Koeffizienten des Polynoms (aufsteigend)
// x: Argument
// Rückgabe: Ableitung an der Stelle x
function HornerAbl(const n: integer; const c: array of extended;
                     const x: extended): extended;
var
  i: integer;
begin
  Result:= n*c[n]*x;                                         // y' nach Horner
  for i:= n-1 downto 2 do Result:= (Result + i*c[i])*x;          // berechnen,
  Result:= Result + c[1]
end;

gammatester 28. Jun 2009 13:50

Re: Potenzreihen: Horner
 
Leider ist HornerAbl völlig falsch für n=0, oder n=1!

n=0: y=c[0], y'=0, HornerAbl: c[1]!! Das ist noch nicht mal definiert!

n=1: y=c[0]+x*c[1], y'=c[1], HornerAbl: c[1] + c[1]*x!

Gammatester

gammatester 28. Jun 2009 16:25

Re: Potenzreihen: Horner
 
Auch HornerFkt ist buggy. Wenn n ein integer ist, darf Result := c[n] im Fall n<0 nicht ausgeführt werden, andernfalls gibt 'nen Rangecheckerror oder 'nen Crash. Am einfachsten via if n>=0 then Result := c[n] else Result := 0.0;

Entsprechendes gilt selbstredend auch für HornerAbl.

Gammatester

alzaimar 29. Jun 2009 06:56

Re: Potenzreihen: Horner
 
Die Rangecheck-Problematik könnte man mit dem richtigen Datentyp implizit vermeiden: Kandidaten wären "Byte","Word" oder "Cardinal".

gammatester 29. Jun 2009 08:38

Re: Potenzreihen: Horner
 
Zitat:

Zitat von alzaimar
Die Rangecheck-Problematik könnte man mit dem richtigen Datentyp implizit vermeiden: Kandidaten wären "Byte","Word" oder "Cardinal".

Genau! Bei der Gelegenheit kann man sich dann auch um zu großes n kümmern. Es gibt zwei Möglichkeiten: Entweder Rangecheck-Fehler oder Abschneiden. Hier mal ein Codeschnipsel, der hoffentlich alle bisherigen Argumente berücksichtigt.

Delphi-Quellcode:
{$define Horner_RTE}  {Fehler falls n>high(c), sonst wird n auf high(c) beschränkt}

{---------------------------------------------------------------------------}
function HornerFkt(n: cardinal; const c: array of extended; x: extended): extended;
  {-HornerFkt - Berechnet den Funktionswert eines Polynoms}
  { n: Grad des Polynoms                                 }
  { c: Koeffizienten des Polynoms (aufsteigend)          }
  { x: Argument                                          }
  { Result: Funktionswert an der Stelle x                }
var
  i: cardinal;
begin
  if n>high(c) then begin
    {$ifdef Horner_RTE}
      RunError(201);
    {$else}
      n := high(c)
    {$endif}
  end;
  Result := 0.0;
  for i:= n downto 0 do Result:= Result*x + c[i];
end;

{---------------------------------------------------------------------------}
function HornerAbl(n: cardinal; const c: array of extended; x: extended): extended;
  {-HornerAbl - Berechnet die Ableitung eines Polynoms}
  { n: Grad des Polynoms                             }
  { c: Koeffizienten des Polynoms (aufsteigend)      }
  { x: Argument                                      }
  { Result: Ableitung an der Stelle x                }
var
  i: cardinal;
begin
  if n>high(c) then begin
    {$ifdef Horner_RTE}
      RunError(201);
    {$else}
      n := high(c)
    {$endif}
  end;
  Result:= 0.0;
  for i:= n downto 1 do Result:= Result*x + i*c[i];
end;
Edit: Habe zu hause noch mal die for-Schleife in HornerAbl korrigiert. :)

sirius 25. Nov 2009 09:44

Re: Potenzreihen: Horner
 
Ist HornerFkt evtl dasselbe, was in Math.Poly steht?

gammatester 25. Nov 2009 11:18

Re: Potenzreihen: Horner
 
Zitat:

Zitat von sirius
Ist HornerFkt evtl dasselbe, was in Math.Poly steht?

Fast, aber halt nicht ganz: Bei math.poly hat man keine Wahl, was den Grad des Polynoms betrifft. Wenn poly(x) = c[0] + c[1]*x + c[2]*x^2 + ... + c[m]*x^m ist, kann man bei HornerFkt n<=m eingegeben und math.poly rechnet immer mit n=m.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz