namespace dislin{
#include "D:\Programme\Libs\Dislin\Dislin.h"
}
#include <stdio.h>
#include <stdlib.h>
#include <math.h>



/*
double V(double x)
{
return ( 0.01875*(5*x*x*x*x*x*x  - 40*x*x*x*x  + 108*x*x));
}
*/
/*
double V(double x)
{
const double Hoehe = 500;
if((sqrt(x*x))<2.5)
{
return (0);
}
else
{
	return (Hoehe);
}
}
*/

double V(double x)
{
return (0.5*x*x);
}

double SchrGl(double x, double y, double E)
{
const double m = 1.00;
const double hbar = 1.00;

return (2*m/(hbar*hbar))*(V(x) - E)*y;
}
double WellenFkt(double E,bool PI, bool print)
{
//Variablen Deklaration
const int m = 12001;				// Schriite
double x,xa,xb;					// Zu untersuchendes Intervall
double fmax = 0, fmin = 0;			// maximale Fkt.Werte (fr Plott)
double h;					// Schrittweite
double graf[3][m];				// x, phi(x), phi'(x)
double y, ydot;					// wird zur iteration der DGL bentigt (zwischen Speichern von phi(x),phi'(x)
double k[3];					// Koeffizienten fr Integration
int i=0;					// Zhlvariable (mehrfach genutzt)


// Startwerte
x = 0;						
xa = -100;
while((x-xa)>0.005)				// Klassischen Umkehrpunkt durch inverall Schachtelung suchen
{
	if (V((x+xa)/2)<E){x  = (x+xa)/2;}
	if (V((x+xa)/2)>E){xa = (x+xa)/2;}
}
xa = xa - 3;					// Startpunkt im kl. verbotenem Bereich (umkehrpkt. -3)	
x = xa;

//y = 0.02;					// infestimal keine startwerte fr phi(x) 
//ydot = 0.01;					// und phi'(x)

y = 0.2;
ydot = 0.1;

xb = 0;						// Endpunkt bei Null

h= (xb-xa)/m;					// Schrittweite festlegen



// Integration der DGL
i=0;
while(i<m)
{
	k[0] = h*SchrGl(x         , y						     ,E);
	k[1] = h*SchrGl(x + 0.5*h , y + 0.5*h*ydot + 0.125*h*k[0],E);	
	k[2] = h*SchrGl(x + h     , y +     h*ydot +   0.5*h*k[1],E);

	y    = y    + h*(1.00/6.00)*(6.0*ydot + k[0] + 2.0*k[1]);
	ydot = ydot +   (1.00/6.00)*(k[0] + 4*k[1] + k[2]);

	//printf("%f \t %f \n", y,ydot);

	graf[0][i] = x;
	graf[1][i] = y;
	graf[2][i] = ydot;
	x = x + h;
	i++;
}


// Bestimme supremum(phi(x)) und infinum(phi(x))
i=0;
while(i<m)
{
	//graf[1][i] = graf[1][i]/Integral;
	//graf[2][i] = graf[2][i]/Integral;
	if(fmax<graf[1][i])	
		{fmax=graf[1][i];}
	if(fmin>graf[1][i])	
		{fmin=graf[1][i];}
	i++;
}

// Normiere Lsung auf max(supremum(phi(x)),infinum(phi(x))) = 1
i=0;
if ((fmax*fmax)>(fmin*fmin))
{
	while(i<m)
	{
		graf[1][i] = graf[1][i]/fmax;
		graf[2][i] = graf[2][i]/fmax;
		//printf("y = %f \t ydot = %f \n", graf[1][i], graf[2][i]);
		i++;
	}
}
else
{
	while(i<m)
	{
		graf[1][i] = graf[1][i]/fmin;
		graf[2][i] = graf[2][i]/fmin;
		//printf("i = %i \n", i);
		i++;
	}
}



// Lsung zeichnen
if (print == true)
{
	dislin::graf(xa,xb,xa,(xb-xa)/10,-1.05,1.05,1.00,0.25);	
	dislin::hsymbl(3);
	i=0;
	while(i<m)
	{
		dislin::rlsymb(21,graf[0][i],graf[1][i]);
		dislin::sendbf();
		i++;
	}
	dislin::endgrf();
}


// Rckgabe entweder von phi(x) oder phi'(x)
if(PI == false)
{
	return graf[2][m-1];
}
else
{
	return graf[1][m-1];
}	
}

void main()
{


//Variablen Deklaration
bool PI = false;		// Paritt false:=gerade, true:=ungerade
double Ealt = 0.01;		// Energie Nivea, bei dem gestartet werden soll
double Eneu = 4.0;		// Korrigierte Energieniveau (hier |Ealt| > |Ealt| + 1, damit Proam in erste Schleife geht)
double Eabw = 1.0;		// Variable zum vergleichen der Energien
double Edelta = 0.000005;	// Schrittweite der Energie im Newtonverfahren
double waste;			// wird bentigt und die Lsung zeichnen zu lassen
int i=0;			// Zhlvariable, wird mehrach genutzt
int n = 6;			// Anzahl der zu suchenden Energieniveaus



dislin::metafl("XWIN");
dislin::scrmod("reverse");                 
dislin::disini();
dislin::name("x","X");
dislin::name("phi(x)","Y");
//dislin::graf(-10,0,-10,5,-1.05,1.05,-1,1);	
//dislin::hsymbl(3);

while(i<n)
{
waste = WellenFkt(Ealt,PI,true);

while(Eabw>0.00005)
{


// ZweiPunktForm
/*Eneu = Ealt - ((WellenFkt(Ealt,PI,false)*Edelta)/
			   (WellenFkt(Ealt + Edelta,PI,false)
			  - WellenFkt(Ealt,PI,false)));
			  */

//Fnfpunktform
Eneu = Ealt - 12*Edelta*WellenFkt(Ealt,PI,false)/
				   (WellenFkt(Ealt - 2*Edelta,PI,false) 
				- 8*WellenFkt(Ealt - Edelta,PI,false) 
				+ 8*WellenFkt(Ealt+Edelta,PI,false) 
				- WellenFkt(Ealt + 2*Edelta,PI,false));
waste = WellenFkt(Eneu,PI,true);
printf("Eneu = %f \n", Eneu);
Eabw = sqrt((Ealt-Eneu)*(Ealt-Eneu));
Ealt = Eneu;

}
dislin::erase();
printf("neachstes Niveau \n");
Ealt = Ealt + 0.5;
Eabw = 1.0;
PI = !PI;
++i;


}

dislin::disfin();
printf("ENDE");



}