Komplex "i"
-
Hallo erstmal,
würde Hilfe bezüglich eines Programms brauchen:
Kann mir vlt jmd sagen wie man die komplexe Zahl "i" in c++ implementiert. und nur "i" alleine. Würde es zum lösen in der zeitabhängigen schrödingergleichung brauchen.
ich habe es mitcomplex<double> aa(0,1);versucht, aber wenn ich die zahl quadriere,(zb.:
aa.imag()*aa.imag()
) kommt "1" statt "-1" heraus.
danke für die hilfe schon mal!!
-
Quadrieren geht ja auch mit
aa*aa
-
danke,
so krieg ich zwar "-1" heraus, aber ich habe noch immer das problem, dass ich "i" alleine nicht in die formel implementieren kann...
wenn ich alsocomplex<double> aa(0,1.); phi[i].real()= exp([b]aa[/b]*x*y)*exp(-((x-x0)*(x-x0))/(2*s*s));bekomme ich eine fehlermeldung...
und wenn ich es nur den imaginärteil nehme stimmt die formel nicht...
oder bin ich komplett verkehrt!?
-
Was für eine Fehlermeldung?
-
real() liefert den Realteil deiner komplexen Zahl als Kopie. Dem etwas zuweisen zu wollen ist recht sinnlos. Lass das doch einfach weg.
Außerdem liefert exp(aa*x*y) als Ergebnis ja wieder eine complex<>.
-
|21|error: no match for 'operator*' in 'std::operator* [with _Tp = double](((const std::complex<double>&)((const std::complex<double>)(&aa))), ((const double&)((const double)(&q)))) * i'|
-
Braunstein schrieb:
real() liefert den Realteil deiner komplexen Zahl als Kopie. Dem etwas zuweisen zu wollen ist recht sinnlos. Lass das doch einfach weg.
Außerdem liefert exp(aa*x*y) als Ergebnis ja wieder eine complex<>.mhm... aber es kommt auch bei
phi[i].imag()= exp(aa*q*i)*exp(-((i-x0)*(i-x0))/(2*sigma*sigma));oder
phi[i]= exp(aa*q*i)*exp(-((i-x0)*(i-x0))/(2*sigma*sigma));die fehlermeldung:
|21|error: no match for 'operator*' in 'std::operator* [with _Tp = double](((const std::complex<double>&)((const std::complex<double>)(&aa))), ((const double&)((const double)(&q)))) * i'|
und ich brauche für später sowohl den imaginär- als auch den komplexteil.
(ich bin ein richtiger programmier anfänger...habe daher auch probleme die fehlermeldungen zu verstehen!)
-
So nebenbei: Mit (x-x0)*(x-x0) rechnest Du x-x0 2mal aus. Das kannst Du vermeiden, indem Du dir eine Funktion zum Quadrieren schreibst:
typedef std::complex<double> cmplxd; inline cmplxd square(cmplxd x) { return x*x; }und die dann einfach so aufrufst
square(x-x0)Und selbst da wird dann ein Produkt doppelt ausgerechnet (x.real()*x.imag()). Das kann man dann noch so vermeiden:
inline double square(double x) { return x*x; } inline cmplxd square(cmplxd x) { return cmplxd( square(x.real())-square(x.imag()), 2*x.real()*x.imag() ); }
-
Reduzier mal bitte deine Formel auf das "aa * q *i", und schau, ob die Fehlermeldung immernoch kommt. Danach zeig uns mal den nötigen Code, d.h. die Definitionen von aa, q und i. Dieses gecaste in dem Ausdruck der Fehlermeldung macht mich stutzig.
-
Sagandscha schrieb:
|21|error: no match for 'operator*' in 'std::operator* [with _Tp = double](((const std::complex<double>&)((const std::complex<double>)(&aa))), ((const double&)((const double)(&q)))) * i'|
(ich bin ein richtiger programmier anfänger...habe daher auch probleme die fehlermeldungen zu verstehen!)
Ich übersetze mal: Der Compiler hat versucht für
irgendwas_vom_typ_complex_double * iden passenden Multiplikationsoperator rauszusuchen, um dieses Produkt auswerten zu können. Das ist ihm nicht gelungen. Ich rate mal, dass hier 'i' eine int-Variable ist. Leider kannst Du complex<double>-Werte nur mit anderen double-Werten multiplizieren. Das ist eine Macke des C++ Standards. Du musst also i durch ein double ersetzen:
irgendwas_vom_typ_complex_double * double(i)Probier das mal.
Der entsprechende Operator ist leider folgendermaßen als freies Template implementiert worden:
// Operator aus der Standardbibliothek template<class T> complex<T> operator*(complex<T>, T const&);Beachte: Das T taucht hier 2mal auf. Für den ersten Parameter müsste man T=double verwenden, für den zweiten dann T=int. Das ist ein Widerspruch, und somit wird dieses Funktionstemplate einfach ignoriert. Da nichts anderes Passendes übrig bleibt, bekommst Du diese Fehlermeldung. Machst Du aus dem zweiten Operand ein double, kann der Compiler mit T=double diesen Operator finden und anwenden.
Heutzutage ist man da schlauer und man würde die "Template Argument Deduction" für den zweiten Parameter mit einem Trick unterdrücken:
// Wie man es hätte besser machen können: template<class T> complex<T> operator*(complex<T>, typename identity<T>::type const&);wobei das typename identity-Zeug drum herum den Typ nicht wirklich verändert. Damit wird nur verhindert, dass der Compiler sich den zweiten Parameter überhaupt anguckt, wenn er sich fragt, was T hier sein soll. Mit diesem Ansatz würde der int implizit zu double konvertiert werden und dann mit dem complex<double> multipliziert werden.
Der Vollständigkeit wegen:
template<class T> struct identity { typedef T type; };
-
habe es soweit umgeschrieben... und es läuft...
danke euch vielmals für die schnelle hilfe!#include<iostream> #include<complex> #include<fstream> using namespace std; int main(){ const int n=1000; const double dt=0.01; double ii=0; double q=0; double x0=100.; double sigma=25.; complex<double> phi[n]; complex<double> aa(0,1.); ofstream raus("daten.dat"); for(int i=0; i<n; i++){ ii=i; phi[i]= exp(aa*q*ii)*exp(-((i-x0)*(i-x0))/(2*sigma*sigma)); } for(int j=0; j<10; j++){ raus<<j<<"\t"<<phi[j].real()<<"\t"<<phi[j].imag()<<"\t"<<norm(phi[j])<<"\n"; } }werde es abe noch umschreiben... die grundfunktion geht ja jetzt!
danke euch!