#ifndef WAVEFUNCTION_H
#define WAVEFUNCTION_H
#include"Cvec.h"
#include<complex>
typedef std::complex<double> Creal;


class Wavefunction :public Cvec {
protected:
	double& dx;
	double E0 = 0.0;		// Groundstate energy

public:
	// initialize wavefunction with step dxin
	Wavefunction(double& dxin);
	// initialize wavefunction with length n and step dxin
	Wavefunction(const int n, double& dxin);

	//---------Functions---------
	// complex scalarproduct (numerical integral) of Wavefunction and rhs [sum(conj(this)*rhs)*dx]
	Creal scalar(Wavefunction& rhs);
	// norm of Wavefunction (scalarproduct with itself)
	double norm();
	// normaliziation of Wavefunction (divide by sqrt(norm))
	void normalize();

	// get space step dx
	double& get_dx() const;

	void set_energy(double Energy);
	double get_energy() const;

	Wavefunction& operator=(const double& in);
	// set every entrty of wavefunction to corresponding entry of "in"
	Wavefunction& operator=(const Wavefunction& in);
	// subtraction of every entry of "in" from corresponding entry of wavefunction
	Wavefunction operator-(const Wavefunction& in);
	// divide every entry of wavefunction by (real) "in"
	Wavefunction operator/(const double& in);
	// multiply every entry of wavefunction with (real) "in"
	Wavefunction operator*(const double& in);
	// multiply every entry of wavefunction with (complex) "in"
	Wavefunction operator*(const Creal& in);
	// multiply every entry of Cvec with corresponding entry of "in"
	Wavefunction operator*(const Cvec& in);

	bool operator<(const Wavefunction& in) const;
	bool operator>(const Wavefunction& in) const;

	// addition of (real) "d" to every entry of wavefunction "vin"
	friend Wavefunction operator+(const double& d, const Wavefunction& vin) {
		Wavefunction out(vin.size, vin.dx);
		for (int i = 0; i < vin.size; i++) out.vec[i] = vin.vec[i] + d;
		return out;
	};

	// initialize gaussian wave over xlist with width "sigma", mean "x0", wavevector "k"
	void init_gauss(Cvec xlist, double x0, double sigma, double k);

	void init_gauss_time(Cvec xlist, double x0, double sigma, double k, double t);
	// initialiez plane wave over xlist with amplitude "Ampl", wavevector "k", phase "phase"
	void init_planeWave(Cvec xlist, Creal Ampl, double k, double phase);
	// initialize random entries
	void init_random();
};


#endif
