Definition von complex ?
-
Ich möchte eine Klasse von std::complex ableiten und suche dafür die Klassendefinitionen. Leider kann ich im Netz dazu überhaupt nichts brauchbares finden.
Konkret suche ich die Abfragung von Real und Imaginar und Ffunktionen wie phase, amplitude sowie setphase und setamplitude.
Matthias
-
-
Also ich finde da nichts, mal abgesehen davon dass mir vollkommen unklar ist was diess Produkt mit den std Klassen zu tun hat.
Matthias
-
pospiech schrieb:
Ich möchte eine Klasse von std::complex ableiten und suche dafür die Klassendefinitionen.
...
Konkret suche ich die Abfragung von Real und Imaginar und Ffunktionen wie phase, amplitude sowie setphase und setamplitude.ich versteh nicht ganz wo das problem liegt? leite halt einfach von std::complex ab!? wofür musst du dazu die definition kennen (die ist sowieso implementation defined oder nicht!?)
achja, warum genau willst du von std::complex ableiten?
-
pospiech schrieb:
Ich möchte eine Klasse von std::complex ableiten und suche dafür die Klassendefinitionen. Leider kann ich im Netz dazu überhaupt nichts brauchbares finden.
Hallo Matthias,
Als Basisklasse ist std::complex nicht vorgesehen. Du solltest das Ableiten möglichst vermeiden. Was hast Du denn genau vor?
Die Klassendefinietion findest Du im Standard-Header complex. Also einfach#include <complex>
pospiech schrieb:
Konkret suche ich die Abfragung von Real und Imaginar und Ffunktionen wie phase, amplitude sowie setphase und setamplitude.
Die einzelnen Größen kannst Du so abfragen:
const double PI = acos( -1.0 ); complex< double > c( 2, -1.5 ); cout << "Realteil: " << real( c ) << " Imaginaerteil: " << imag( c ) << endl; cout << "Betrag: " << abs( c ) << " Phase: " << arg( c ) * 180./PI << "Grad" << endl;
Das Setzen einzelner Größen ist nicht vorgesehen und macht auch keinen Sinn. Man kann natürlich eine komplexe Zahl mit einer anderen überschreiben, also etwa so
complex< double > d = polar( abs( c ), 45.0 * PI/180. ); // gleicher Betrag wie c mit Phase 45Grad
Gruß
Werner
-
dot schrieb:
achja, warum genau willst du von std::complex ableiten?
Ich habe eine complex Klasse die nicht auf std:complex aufbaut. Jetzt würde ich gerne die Möglichkeiten von std::complex nutzen aber die Funktionen von der alten Complex Klasse erhalten.
Daher wollte ich diese Klasse umschreiben indem ich sie von std:complex ableite.
Aber wenn es keine Dokumentation gibt wie diese Implementiert ist wird das unmöglich. Wobei es mich wundert das man einfach nichts im Internet dazu findet.Matthias
-
Bist du ein Troll? Scheinbar kennst du die Grundlagen von C++ ja bereits und von der Standardbibliothek hast du offensichtlich auch schon was gehört. Warum schaust du dir dann nicht einfach die Dokumentation zur Schnittstelle von std::complex an?
Im zweiten Posting findest du ein Link zu einer Implementierung der Standardbibliothek und der Dokumentation zu dieser.
-
pospiech schrieb:
Ich habe eine complex Klasse die nicht auf std:complex aufbaut. Jetzt würde ich gerne die Möglichkeiten von std::complex nutzen aber die Funktionen von der alten Complex Klasse erhalten.
Hallo Matthias,
welche Funktionalität hat Deine Klasse, die std::complex nicht hat?
Ansonsten findest Du auch hier noch Dokumentation dazu.
Gruß
Werner
-
Werner Salomon schrieb:
welche Funktionalität hat Deine Klasse, die std::complex nicht hat?
Es hat zusätzlich die Funktionen
.getphase()
.getamplitude()
.setphase(const double)
.setamplitude(const double)Das hat den Vorteil das eine Funktion die ein CComplex zurückgibt, gleichzeit auch die Phase ausgeben kann als
double phase = DataClass.getvalue().phase()Mit std::complex kann ich zwar auch phase und amplitude erhalten aber nicht als Funktion der Klasse (in std::complex sind es "arg" und "abs").
Matthias
-
pospiech schrieb:
Es hat zusätzlich die Funktionen
.getphase()
.getamplitude()
.setphase(const double)
.setamplitude(const double)Das hat den Vorteil das eine Funktion die ein CComplex zurückgibt, gleichzeit auch die Phase ausgeben kann als
double phase = DataClass.getvalue().phase()Hallo Matthias,
das funktioniert doch mit std::complex genauso:
double phase = arg( DataClass.getvalue() );
pospiech schrieb:
Mit std::complex kann ich zwar auch phase und amplitude erhalten aber nicht als Funktion der Klasse (in std::complex sind es "arg" und "abs").
Wo ist da denn das Problem? double hat ja auch keine Methode sin()!
Dass das Setzen von einzelnen Werte keine gute Idee ist, habe ich am 11.09 schon versucht darzustellen.
Werner Salomon schrieb:
Das Setzen einzelner Größen ist nicht vorgesehen und macht auch keinen Sinn. Man kann natürlich eine komplexe Zahl mit einer anderen überschreiben, also etwa so
complex< double > d = polar( abs( c ), 45.0 * PI/180. ); // gleicher Betrag wie c mit Phase 45Grad
Das Verlangen, die Werte einzeln zu setzen resultiert im Allgemeinen aus einem Designfehler. Erklär' doch mal, wozu Du das Setzen von Amplitude und Phase benötigst.
Gruß
Werner
-
Werner Salomon schrieb:
Das Verlangen, die Werte einzeln zu setzen resultiert im Allgemeinen aus einem Designfehler. Erklär' doch mal, wozu Du das Setzen von Amplitude und Phase benötigst.
Ich beschreibe ein elektromagentisches Feld mit a * exp(i phi), also eine Komplexe Zahl mit den Informationen Amplitude und Phase. Da ich dabei die Werte Amplitude und Phase einzelne Abfragen und Manipulieren muss sind für mich diese Funktionen von enormem Vorteil.
Warum es keinen sinn machen sollte bei gleicher Phase die Amplitude zu ändern oder umgekehrt erschließt sich mir überhaupt nicht. Insbesondere da es die mathemtatische Operation ist die ich dauernd benötige.
Matthias
-
pospiech schrieb:
Warum es keinen sinn machen sollte bei gleicher Phase die Amplitude zu ändern oder umgekehrt erschließt sich mir überhaupt nicht. Insbesondere da es die mathemtatische Operation ist die ich dauernd benötige.
Ok .. mal ganz konkret. Wie sieht die Operation aus, bei der die Amplitude bei unveränderter Phase gesetzt werden muss. Wie wird dieser Wert für die Amplitude in diesem Fall bestimmt?
-
Werner Salomon schrieb:
pospiech schrieb:
Warum es keinen sinn machen sollte bei gleicher Phase die Amplitude zu ändern oder umgekehrt erschließt sich mir überhaupt nicht. Insbesondere da es die mathemtatische Operation ist die ich dauernd benötige.
Ok .. mal ganz konkret. Wie sieht die Operation aus, bei der die Amplitude bei unveränderter Phase gesetzt werden muss. Wie wird dieser Wert für die Amplitude in diesem Fall bestimmt?
Ich bestimme das in meiner Klasse so:
inline double phase(){ return atan2(this->im,this->re);}; // atan2(x,y) = atan(x/y) inline double amplitude(){ return sqrt(this->re*this->re+this->im*this->im);}; inline void setphase(double phase) { double CurrAmpl; CurrAmpl = amplitude(); this->re = CurrAmpl * cos(phase); this->im = CurrAmpl * sin(phase); } inline void setamplitude(double amplitude) { double CurrPhase; CurrPhase = phase(); this->re = amplitude * cos(CurrPhase); this->im = amplitude * sin(CurrPhase); }
wobei es mathematisch sowies kein Problem ist, da ich von einer Komplexen Zahl immer Amplitude oder Phase bestimmen kann und über c = a *exp(i phi) immer beides setzen kann.
Unsinnig wird es nur bei Amplitude = 0 die Phase zu setzen.
Matthias
-
Hallo Matthias,
Ich habe mich vielleicht unklar ausgedrückt. Meine Frage war wo - bzw. in welchem Kontext - z.B. dieses 'setamplitude()' aufgerufen wird, und wie der Parameter 'amplitude' vor dem Aufruf bestimmt wurde. Ist dieser Wert von 'amplitude' von dem ursprünglichen Wert der komplexen Zahl (this->re; this->im) irgendwie abhängig?
Gruß
Werner
-
Werner Salomon schrieb:
Ist dieser Wert von 'amplitude' von dem ursprünglichen Wert der komplexen Zahl (this->re; this->im) irgendwie abhängig?
Ich habe 2D Arrays dieser Komplexen Zahlen und setze die Amplitude der Complexen Zahlen in der Regel anhand einer Formel(x,y). Die gesetzten Werte sind damit nicht von dem vorherigen Wert der Complexen Zahl abhängig.
Matthias
-
Um die Amplitude einer komplexen Zahl zu aendern muss man sie doch einfach mit einem entsprechenden Faktor multiplizieren, wenn ich jetzt nicht voellig auf dem Schlauch stehe. Ganz ohne ableiten und ganz ohne cos()-sin() rumspielen sieht das dann so aus:
template<typename T, typename U> void SetAmplitude(std::complex<T>& val, U amp) { val *= amp/val.amplitude(); }
Bezeichnet man val (vorher) mit v, die amplitude (vorher) mit a, val (nachher) mit v' und amp mit a', dann schreibt sich das so:
/edit: wenn die gesetzten Werte wie du sagst garnicht vom vorherigen Wert der Zahl abhaengig sind, impliziert das, dass du nicht nur die Amplitude aenderst, sondern auch die Phase. Dann muesstest du allerdings die neue Phase mit angeben.
-
pumuckl schrieb:
wenn die gesetzten Werte wie du sagst garnicht vom vorherigen Wert der Zahl abhaengig sind, impliziert das, dass du nicht nur die Amplitude aenderst, sondern auch die Phase. Dann muesstest du allerdings die neue Phase mit angeben.
Die Amplitude die ich setzen möchte hängt nicht davon ab. Dieser Wert ändert beim Setzten nicht die Phase, aber natürlich den Real und Imaginärteil. Aber wozu diese ganze mathemtische Diskussion dienen soll ist mir noch immer unklar.
Matthias
-
Werner Salomon schrieb:
Dass das Setzen von einzelnen Werte keine gute Idee ist, habe ich am 11.09 schon versucht darzustellen.
Werner Salomon schrieb:
Das Setzen einzelner Größen ist nicht vorgesehen und macht auch keinen Sinn. Man kann natürlich eine komplexe Zahl mit einer anderen überschreiben, also etwa so
complex< double > d = polar( abs( c ), 45.0 * PI/180. ); // gleicher Betrag wie c mit Phase 45Grad
Das Verlangen, die Werte einzeln zu setzen resultiert im Allgemeinen aus einem Designfehler. Erklär' doch mal, wozu Du das Setzen von Amplitude und Phase benötigst.
Warum sollte das ein Designfehler sein? Was ist schlimm daran, wenn ich eine Phasenverschiebung durchführen will? Oder nur die Amplitude ändern möchte? Ist ein sinnvoller Algorithmus, der das tun möchte wirklich unvorstellbar?
-
pumuckl schrieb:
Um die Amplitude einer komplexen Zahl zu aendern muss man sie doch einfach mit einem entsprechenden Faktor multiplizieren, wenn ich jetzt nicht voellig auf dem Schlauch stehe.
ja und genau darum geht es hier eben NICHT. Matthias möchte nicht z.B. die Amplitude um den Faktor 2 vergrößern - klar das erreicht man auch durch Multiplikation der komplexen Zahl mit 2 - sondern Matthias möchte eine setAmplitude-Methode (s. sein Posting vom 19.02 23:47).
Ich behaupte nun - aus Erfahrung mit solchen Werten und aus einem Bauchgefühl heraus - das eigentliche Problem steckt woanders.
Jester schrieb:
Warum sollte das ein Designfehler sein? Was ist schlimm daran, wenn ich eine Phasenverschiebung durchführen will? Oder nur die Amplitude ändern möchte? Ist ein sinnvoller Algorithmus, der das tun möchte wirklich unvorstellbar?
Es ist nicht schlimm, die Amplitude zu verändern, sondern es ist meistens ein Hinweis auf ein Problem woanders, wenn man sie neu Setzen möchte.
pospiech schrieb:
Ich habe 2D Arrays dieser Komplexen Zahlen und setze die Amplitude der Complexen Zahlen in der Regel anhand einer Formel(x,y). Die gesetzten Werte sind damit nicht von dem vorherigen Wert der Complexen Zahl abhängig.
Die Amplitude die ich setzen möchte hängt nicht davon ab. Dieser Wert ändert beim Setzten nicht die Phase, aber natürlich den Real und Imaginärteil. Aber wozu diese ganze mathemtische Diskussion dienen soll ist mir noch immer unklar.
Hallo Matthias,
Ich versuche mal - zusammen mit dem was Du uns bisher mitgeteilt hast - meine Glaskugel zu befragen.Ich vermute: Du hast zwei 2D-Arrays; eines mit den Werten für die Amplitude und eines mit den Werten für die Phase. Jetzt musst Du diese Werte irgendwie da rausholen, um mit ihnen zu arbeiten. Dazu hast Du an zwei Codestellen eine doppelte Schleife (über x und über y des jeweiligen 2D-Arrays) und schaufelst dort jeweils getrennt einmal Amplitude und einmal Phase in Deine Struktur oder Klasse.
Wenn das so sein sollte, dann liegt der von mir vorher erwähnte 'Designfehler' bereits in der Tatsache, dass es diese beiden 2D-Arrays anstatt eines 2D-Arrays mit komplexen Werten gibt.
Dieser Umstand führt nämlich zu doppeltem Code (zwei mal zwei Schleifen), der auch noch redundant ist - es wird ja jedesmal im Prinzip das gleiche getan. Und genau diese sollte man bei der Programmierung vermeiden. Daher nenne ich das Designfehler. Das ist jetzt nichts Schlimmes - hat aber evt. Folgen - wie das Verlangen nach einer Set-Methode.
Negativ zu werten wäre (ich bin immer noch beim Konjunktiv) dann auch der Umstand, dass Du die Reihenfolge beachten müsstest, mit der die beiden Doppelschleifen aufgerufen werden. Es müsste - wie Du selbst bereits erwähnt hast - zunächst die Amplitude und dann erst die Phase "gesetzt" werden, weil umgekehrt das Setzen der Phase sinnlos ist.
Das wäre jetzt alles nicht die Katastrophe - das ist auch nicht so viel Code, dass man gleich die Übersicht verlieren würde; aber wehre den Anfängen.
Wenn Du nur eine Doppelschleife hast, in der Du auf beide 2D-Arrays gleichzeitig zugreifst, so kannst Du aus einer Amplitude und einer Phase leicht eine komplexe Variable mit
std::complex< double > c = std::polar( amplitude, phase );
direkt erzeugen. Du benötigst kein einseitiges Set und Dein Code wäre im ganzen weniger und besser - immer alles vorausgesetzt, meine Glaskugel funktioniert.
Gruß
Werner
-
Werner Salomon schrieb:
Jester schrieb:
Warum sollte das ein Designfehler sein? Was ist schlimm daran, wenn ich eine Phasenverschiebung durchführen will? Oder nur die Amplitude ändern möchte? Ist ein sinnvoller Algorithmus, der das tun möchte wirklich unvorstellbar?
Es ist nicht schlimm, die Amplitude zu verändern, sondern es ist meistens ein Hinweis auf ein Problem woanders, wenn man sie neu Setzen möchte.
Warum? Ist es auch ein Hinweis auf ein Problem woanders, wenn ich eine int-variable neu setzen möchte? Wo liegt der qualitative Unterschied?