Aufgabe 15 - kubische Splines

Aufgabe 15 - kubische Splines

Beitragvon Kazaar » 24.05.2010 15:54

Hallo,
ich möchte als Orientierung eine Alternative zur Musterlösung anbieten (meine eigene Lösung). Es funktioniert, aber die Musterlösung ist bestimmt viel besser. ;) Schlau wäre es auf jeden Fall, die ganzen Formeln von woanders zu kopieren, statt sie selbst zu tippen, wie ich das gemacht hab...

Code: Alles auswählen
/*
* source.cpp
*
*  Created on: 24.05.2010
*      Author: Kazaar
*       Title: Aufgabe 15
*/

#include <iostream>
#include <fstream>
#include <cmath>

using namespace std;

int main() {
   // Variablen und Konstanten deklarieren
   char dateiname_ein[30] = "a15-interpol.txt"; // Dateiname der Daten
   char dateiname_aus[30] = "ausgabe.txt"; // Dateiname der Ausgabe
   int n_max = 100; // maximale Zahl der Datenpaare
   double x[n_max], y[n_max],
         lambda[n_max], mu[n_max], d[n_max], M[n_max],
         alpha[n_max], beta[n_max], gamma[n_max], delta[n_max];
   int n; // höchster Index der Wertepaare (x[i], y[i] mit i = 0, ..., n)


   // ---- Daten aus Datei einlesen ----

   ifstream einlesen;
   einlesen.open(dateiname_ein);

   // Daten einlesen, solange ein x-Wert da ist
   n = 0;
   cout << "Einlesen..." << endl;
   while (einlesen >> x[n]) { // x-Wert einlesen, dann voraussetzen, dass es auch einen y-Wert gibt
      einlesen >> y[n];
      n++;
   }
   n--; // n gibt jetzt den höchsten Index der Datenpaare an.
   cout << "Es gibt " << n+1 << " Wertepaare." << endl;


   // ---- Kubische Splines berechnen ----

   // lambda[j], mu[j], d[j] berechnen
   // Randwerte
   lambda[0] = 0;
   mu[0] = 2;
   mu[n] = 0;
   d[0] = 0;
   d[n] = 0;

   // Für die folgenden zwei Schleifen das Aufgabenblatt ansehen
   for (int j = 1; j < n; j++) {
      lambda[j] = (x[j+1] - x[j]) / (x[j+1] - x[j-1]);
      mu[j] = (x[j] - x[j-1]) / (x[j+1] - x[j-1]);
      d[j] = 6 / (x[j+1] - x[j-1]) *
            ( ( (y[j+1] - y[j]) / (x[j+1] - x[j]) ) - ( (y[j] - y[j-1]) / (x[j] - x[j-1]) ) );
   }

   for (int i = 1; i <= n; i++) {
      double f; // Zwischenspeicher
      f = - mu[i] / mu[i-1];
      mu[i] = 2 + f * lambda[i-1];
      d[i] += f * d[i-1];
   }

   // Rücksubstitution
   M[n] = d[n] / mu[n];
   for (int i = n-1; i >= 0; i--) {
      M[i] = (d[i] - lambda[i] * M[i+1]) / mu[i];
   }

   // Werte für M[i] ausgeben
   cout << endl << "Ergebnis:\ni\tM[i]\n";
   for (int i = 0; i <= n-1; i++) {
      cout << i << "\t" << M[i] << endl;
   }

   // Koeffizienten der kubischen Splines berechnen
   for (int j = 0; j <= n-1; j++) {
      alpha[j] = y[j];
      beta[j] = (y[j+1] - y[j]) / (x[j+1] - x[j]) - (2 * M[j] + M[j+1]) / 6 * (x[j+1] - x[j]);
      gamma[j] = M[j] / 2;
      delta[j] = (M[j+1] - M[j]) / 6 / (x[j+1] - x[j]);
   }




   // ---- Mit kubischen Splines neue Werte berechnen ----


   // Interpolierte Wertepaare berechnen und in Datei schreiben
   ofstream ausgabe;
   ausgabe.open(dateiname_aus);

   // Variablen für diesen Abschnitt deklarieren
   int anz_interpol = 300; // Anzahl der interpolierten Wertepaare
   double schrittbreite, a, b; // Intervallbreite, interpolierter Funktionswert b(a)
   int j = 0; // Spline-Nummerierung

   schrittbreite = (x[n] - x[0]) / anz_interpol;
   a = x[0]; // links starten, mit Schrittbreite schrittbreite durchlaufen
   j = 0; // mit Spline 0 anfangen

   cout << endl << "Berechne " << anz_interpol << " interpolierte Wertepaare mit Schrittbreite " <<
         schrittbreite << ".\n";
   //cout << "i\ta\tb(a)\n";
   for (int i = 1; i <= anz_interpol; i++) {
      // Feststellen, welcher Spline benutzt werden muss
      while (a > x[j+1]) j++; // nächsten Spline probieren, bis a im Bereich des aktuellen Splines liegt

      b = alpha[j] + beta[j] * (a - x[j]) + gamma[j] * (a - x[j]) * (a - x[j])
            + delta[j] * (a - x[j]) * (a - x[j]) * (a - x[j]);

      //cout << i << "\t" << a << "\t" << b << endl;

      ausgabe << i << "\t" << a << "\t" << b << endl;

      // um schrittbreite weitergehen
      a += schrittbreite;
   }


   ausgabe.close();
   cout << endl << "Berechnete Wertepaare geschrieben in " << dateiname_aus << "." << endl;



   cout << endl << "-- Beendet --" << endl;
   return 0;
}
Kazaar
 
Beiträge: 326
Registriert: 29.10.2008 21:35

Re: Aufgabe 15 - kubische Splines

Beitragvon CommanderTomalak » 24.05.2010 23:54

Ich Idiot hatte echt alles richtig, nur am Schluss den falschen Spline genommen und jetzt STUNDENLANG nach dem Fehler gesucht :evil:
danke, du hast mir echt auf die Sprünge geholfen!
"Das Volk hat das Vertrauen der Regierung verscherzt. Wäre es da nicht doch einfacher, die Regierung löste das Volk auf und wählte ein anderes?"
- Bertolt Brecht
CommanderTomalak
 
Beiträge: 204
Registriert: 19.01.2009 00:42
Wohnort: Karlsruhe

Re: Aufgabe 15 - kubische Splines

Beitragvon reynhold » 25.05.2010 17:14

Wie sieht denn euer geplottetes Zeug aus, bzw. was plottet ihr da überhaupt mit welcher Software?
Bzw. hatte das einer von euch auch dass die ausgegebene Datei für die ersten circa 20 Werte 0 ausgibt, und dann die (fast) richtigen Werte...? :shock:

Ich muss nämlich ehrlich gestehen dass ich keinerlei Ahnung mehr habe, was bei meinem Programm dazuführen könnte.
Benutzeravatar
reynhold
 
Beiträge: 184
Registriert: 26.10.2008 12:09

Re: Aufgabe 15 - kubische Splines

Beitragvon mabl » 25.05.2010 17:26

Ich habe R benutzt um das Teil zu Plotten, siehe Anhang.
Dateianhänge
spline.pdf
Spline Plot
(8.4 KiB) 232-mal heruntergeladen
spline.txt
Spline Data
(4.65 KiB) 225-mal heruntergeladen
Benutzeravatar
mabl
Site Admin
 
Beiträge: 741
Registriert: 25.10.2008 11:28
Wohnort: Ettlingen, Karlsruhe

Re: Aufgabe 15 - kubische Splines

Beitragvon Cashdogg » 25.05.2010 21:27

Meine generierten Punkte sind nicht stetig :? Anscheindend kann man das beheben, indem man zum Schluss in der while-Schleife die x-Werte nicht von unten vergleicht sondern von oben. Wenn ich das aber abändere bekomme ich da immer igrendwelche Fehler in meiner EXE-Datei bzw. die Punkte die rauskommen sind Misst. Könnte mir da jemand mit einem Code der abgeänderten while-Schleife behilflich sein?

Gruß Cashdogg
Cashdogg
 
Beiträge: 408
Registriert: 20.12.2008 15:05

Re: Aufgabe 15 - kubische Splines

Beitragvon M.A. » 25.05.2010 22:19

Ich hab das mit gnuplot zeichnen lassen.
Code: Alles auswählen
plot 'a15-interpol.dat' using 1:2 title 'a15-interpol.dat' with points, 'interpolierte_werte.txt' using 1:2 title 'Interpolation' with dots
Dateianhänge
a15-interpol.png
Plot der gegebenen und interpolierten Werte
(5.41 KiB) Noch nie heruntergeladen
interpolierte_werte.txt
Tabelle der interpolierten Werte, so wie sie mein Programm ausgegeben hat.
(4.94 KiB) 223-mal heruntergeladen
interpol.cpp
Mein Programmcode
(3.59 KiB) 257-mal heruntergeladen
Bild
Benutzeravatar
M.A.
 
Beiträge: 366
Registriert: 25.10.2008 16:37


Zurück zu Programmieren

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron