Interpolation
und
NewtonInterpolation
, neue Klassen LinearerSpline
und LineareSplineInterpolation
f
interpoliert
werden soll und dass somit die InterpolationsFunktion
eine
"Ersatzfunktion" für f
wird, erfasst werden. Bei der
Polynominterpolation kommen hierdurch die T-Knoten ins Spiel. Ferner gibt
es einen Sinn, von einer Interpolationsfehlerfunktion zu reden.
Dazu wird die abstrakte Klasse Interpolation
um ein
Attribut in Form eines Objekts namens
zuInterpolierendeFunktion
der Klasse Funktion
erweitert. Ein zweiter Konstruktor (sowohl in der Klasse
Interpolation
als auch in deren Unterklasse
NewtonInterpolation
) muss her, der dieses Objekt
übergibt und zu gegebenen Knoten die (Interpolations-)Werte durch
Funktionsauswertung berechnet.
Für die grafische Darstellung einer solchen Interpolation bieten
sich zwei Grafikfenster an: in dem ersten werden die beiden
Graphen der Funktionen zuInterpolierendeFunktion
und
InterpolationsFunktion
sowie die Interpolationspunkte, in
einem zweiten Fenster der Graph der Interpolationsfehlerfunktion
sowie die Knoten auf der x-Achse gezeigt. Zu diesem Zweck soll eine
neue (öffentliche) Methode Zeichne()
der Klasse
Interpolation
hinzugefügt werden. Um aber auch den
einfacheren Fall zu erfassen, dass nur Interpolationspunkte gegeben
sind, zu denen eine Interpolationsfunktion berechnet werden soll,
kann man eine Variable vom Typ boolean
als Attribut in
der Klasse Interpolation
einführen, etwa mit dem
Bezeichner FunktionsInterpolation
.
Der Vorteil des OOP macht sich hier ganz deutlich bezahlt, wenn man
eine andere Interpolation als die Polynominterpolation verwendet. Dies
ist das Ziel des Teils 2 der Projektaufgabe 1: An die Stelle der Klasse
NewtonInterpolation
tritt die Klasse
LineareSplineInterpolation
, die das Objekt namens
InterpolationsFunktion
in ihrem Konstruktor völlig
analog zu dem von NewtonInterpolation
berechnet, nur,
dass an die Stelle der Zeilen
die einfachere Zeiledouble[] c = DividierteDifferenzen(); InterpolationsFunktion = new NewtonPolynom(x,c);
tritt, wobei die KlasseInterpolationsFunktion= new LinearerSpline(x,y);
LinearerSpline
eine Unterklasse
von Funktion
ist, deren Methode getY()
natürlich vernünftig implementiert werden muss.
Sind x[]
gegebene Knoten und f
eine zu
interpolierende Funktion, so kann man in einer Applikationsklasse
durch
die Polynominterpolation und durchNewtonInterpolation NIP = new NewtonInterpolation(x,f); NIP.Zeichne();
die lineare Splineinterpolation visualisieren. Ist das nicht eine großartige Anwendung des Vererbungsprinzips des OOP? Später kann auch eineLineareSplineInterpolation SIP = new LineareSplineInterpolation(x,f); SIP.Zeichne();
kubischeSplineInterpolation
hinzukommen.
Kubische Splines
double[] t
), die Werte (double[]
f)
) und die "Steigungen" (double[] s
, Ableitungen
von S an den Knoten) gegeben. Dann ist es nur noch ein kleiner Schritt
zur
Will man eine Interpolationsaufgabe zu den Interpolationspunkten (t[],f[]) lösen, so wissen wir von der Theorie, dass dies durch einen 2-glatten kubischen Spline gelingt, wobei sogar noch zwei Bedingungen frei sind. In jedem Fall muss ein lineares Gleichungssystem mit den Unbekanntes s[] gelöst werden. Wie dies geht, wird bis zum Kapitel "Lineare Gleichungssysteme" aufgeschoben. Klar ist nur schon jetzt, wie vorgegnagen werden muss:public class kubischerSpline extends Funktion{ private double[] t, f, s; //Knoten, Werte, Ableitungen public kubischerSpline(double[] x, double[] y, double[] s){ super(x[0],x[x.length-1]); t=x; f=y; this.s=s; } public double getY(double x){ /*1.Bestimme j mit t[j]<=x<=t[j+1] 2.Werte das durch t[j],f[j],s[j],t[j+1],f[j+1],s[j+1] gegebene kubische Hermite-Interpolationpolynom aus.*/ }//Ende getY }//Ende class kubischerSpline
Danach ist es ein leichtes, die Klassepublic class kubischeSplineInterpolation extends Interpolation{ /* Der Konstruktor %uuml;bergibt die Interpolationspunktedouble[] x, double[] y
(Daten der KlasseInterpolation
), die Festlegung der zwei offenen Bedingungen sowie evtl. einezuInterpolierendeFunktion
. Gegebenenfalls sind mehrere verschiedene Konstruktoren vorzusehen. Innerhalb der Konstruktoren wird mit Hilfe einer späteren KlasseMatrix
das zugehörige lineare Gleichungssystem für die s[] gelöst und mittels */ InterpolationsFunktion k =new kubischerSpline(t,f,s); //berechnet.
NumAnalysis
um
einige Methoden namens SplineInterpolation()
zu
bereichern.
Java-Fallen
Ein häufiger verhängsnisvoller Fehler tritt bei Objekten
derselben Klasse mit unterschiedlichen Namen - sagen wir A1 und A2 -
auf, wenn man A1 schon allokiert hat und mittels A2=A1
eine Kopie anlegen will. Wenn danach A2 verändert wird, so
wird A1 in einem Zug mitverändert, meist ungewollt. Dies liegt
daran, dass A1 und A2 Zeiger- oder Referenzvariable sind, die ab dem
Befehl A2=A1
auf denselben Speicherbereich zeigen. Alle
Änderungen von A1 oder A2 finden in diesem Speicherbereich
statt. BeispieL:
Will man wirklich eine Kopie anlegen, so kommt die Methodedouble[] x={1,2,3}; double[] y; y=x; y[1]=x[1]/2; x[1]*=3; //jetzt gilt x[1]=3=y[1]!! s. Klausuraufgabe
clone()
der obersten Klasse object
zum Zuge: A2=(Klassennamen) A1.clone()
, oder an
unserem Beispiel: y=(double[]) x.clone();
.
Eine am Anfang mysteriöse Laufzeit-Fehlermeldung lautet
NullPointerException
. Diese Meldung tritt immer
dann auf, wenn Objekte nur deklariert, aber nicht allokiert sind (ihre
Variablen sind dann NullPointer
, sie zeigen auf
Null
), man jedoch auf ihre Komponenten zugreifen
will. Z.B. bei einem Feld, das durch double[] x;
deklariert wurde und auf das später etwa durch ... x[2]
...
zugegriffen wird.
Ein weiterer häfiger Fehler entsteht bei der Division von
int
-Zahlen:
int i=3; int j=5; double x=i/j; //liefert x=0 double y=j/i; //liefert y=1 //richtig: double x= (double) i/j; //Casting