Char.Funktion invertieren.



  • Hallo,

    ich möchte ei Programm schreiben, welches die charakteristische Funktion invertiert, um die Verteilung zu berechnen -- die Idee ist :

    Ein Benutzer gibt einen Vektor (eine Liste) normalverteilter Größen an : im Endeffekt muss er also für jede Zufallsgröße zwei Dinge eingeben : Mittelwert und Varianz -- also zwei Vektoren sind einzugeben.

    Seien die Mittelwerte (μ1,.....,μn)(\mu_{1},.....,\mu_{n}) und die Varianzen (σ12,....,σn2)(\sigma_{1}^{2},....,\sigma_{n}^2)

    die charakteristische Funktion meiner Verteilung ist nun :

    f(t)=k=1n112iσk2teitμk21itσk2f(t) = \prod_{k=1}^{n} \frac{1}{\sqrt{1-2i \sigma_{k}^2 t}}e^{\frac{it \mu_{k}^2}{1-it \sigma_{k}^2}}

    also da müssen nun Mittelwerte und Varianzen hinein'gespeist' werden und danach muss folgendes Integral numerisch gelöst werden (mittels Trapezregel zb, weil die doch relativ einfach ist):

    F(x)=12+12π0exp(itx)f(t)exp(itx)f(t)itdtF(x) = \frac{1}{2} + \frac{1}{2 \pi} \int_{0}^{\infty} \frac{exp(itx)f(-t)-exp(-itx)f(t)}{it}dt

    Meine letzte Programmiervorlesung liegt schon eine Zeit zurück, daher möchte ich euch fragen, ob ihr vll Ansätze hättet, die das möglichst schnell zum Ziel führen?

    Bin für jede Antwort dankbar

    LG

    Waldquelle


  • Mod

    Du hast alles schon schön so beschrieben, wie ein Programmierer es tun würde. Ein Ablauf, genau abgegrenzte Objekte und Vorgänge, und so weiter. Fang doch einfach an und setz alles genau so um, wie du es beschrieben hast. Hast du mit irgendeinem dieser Schritte konkrete Schwierigkeiten?



  • Hallo,

    also ich bin Mathematiker - daher auch eine gewisse strukturierte Herangehensweise 🙂 einzig die Syntax (bzw die exakte spezifische Umsetzung) ist manchmal etwas problematisch ... also zb das Einlesen ? über eine for - Schleife ein array befüllen, oder gibts da bessere Zugänge etc -- aber ich programmiere mal los und melde mich dann bei Problemen + hänge ich dann immer den Code an 🙂

    LG



  • Hallo,

    also habe mich dieser Problemstellung wieder angenommen ..

    und zwar mein erstes Problem :

    das Einlesen der Werte ist kein Problem, da diese ganzzahlig sind etwa :

    int eingabe(int k)
    { int z[k];
    int b[k];
    	int i;
    	int y;
    	for(i=0;i<k;i++)
    	{
    		cout <<"Eingabe des" << i << "ten Mittelwertes";
    		cin >> z[i];
    		std::cout << std::endl; 
    		cout <<"Eingabe der" <<i << "ten- Varianz";
    		cin >> b[i];
    		std::cout << std::endl; 
    	}
    }
    

    vermöge dieser einfachen Funktion.

    Nun muss ich diese Werte in

    f(t)=k=1n112iσk2teitμk21itσk2f(t) = \prod_{k=1}^{n} \frac{1}{\sqrt{1-2i \sigma_{k}^2 t}}e^{\frac{it \mu_{k}^2}{1-it \sigma_{k}^2}}

    speisen.
    Wie soll ich das am besten realisieren ? über eine for - Schleife? vor allem .. wie ist es denn am besten auf die Werte zuzugreifen ? (im Hinblick auf die spätere numerische Integration)

    Danke für eure Hilfe,

    Lg Waldquelle


  • Mod

    Das ist schon einmal falsch, insofern als dass das in Zeilen 2 und 3 C ist, sogar ein eher exotisches Feature von C, welches zudem noch falsch benutzt wurde. Felder variabler Größe in C++ macht man mit std::vector (was ein Zufall, wenn man mit der Aufgabenstellung vergleicht 😉 ). Dann klappt das auch mit ganz normalen Übergaben ganz so, wie man intuitiv erwarten würde.



  • Hallo,

    also ich habe das mal <entsprechend deinem Vorschlag> adaptiert.

    #include <iostream>
    #include <cmath>
    #include <complex>
    #include <math.h>
    #include <vector>
    
    using namespace std;
    
    int m;
    
    int eingabe(int m)
    {
    	std::vector<int>m1(m);
    	std::vector<int>m2(m);
    for(int i=0;i<m1.size();i++)
    			{
    					cout <<"Geben Sie dem " << i << "ten Mittelwert ein \n";
    					cin >> m1[i];
    					cout <<"Geben Sie die " << i << "te Varianz ein \n";
    					cin >> m2[i];
    					if( m2[i] < 0)
    					{
    						cout << "Varianzen sind immer positiv"; 
    						break;
    					}
    
    			}
    
    }
    
    int main()
    
    {
    
    int k;
    cout <<"Eingabe der Dimension des Mittelwert u. Varianzvektors \n";
    cin >> k;
    eingabe(k);
    
    }
    

    Verzeihung, falls das alles ein wenig simpel wirkt ... ich muss wirklich erst wieder ins technische beim Programmieren hineinfinden.

    Lg



  • Das größte Problem: Die Vectoren existieren nur innerhalb deiner Funktion eingabe.

    Vectoren haben gegenüber den Arrays den Vorteil, dass sie ihre Größe ändern können.
    Du musst am Anfang nicht wissen wie groß sie werden.

    Wenn du schon mal C++ gelernt hast, dann sollte ein Online-Tutorial dich da wieder rein bringen.
    Wenn nicht, dann brauchst du ein Buch!

    Mach doch erstmal die Berechnung.
    Die Eingabdaten kannst du am Anfang noch im Code fest vorgeben und später dann eine User-Eingabe vorsehen.



  • das c++ spezifische könnte so in etwa aussehen:

    #include <iostream>
    #include <vector>
    
    std::vector<int> give_vector( const char* what = nullptr)
    {
      std::vector<int> ret_val;
    
      if( what )
        std::cout << what << '\n';
    
      for( int to_add; std::cin >> to_add; )
        ret_val.push_back( to_add );
    
      std::cin.clear();
      return ret_val;
    } 
    
    float integral_ausrechnen_mittels_trapzeregel(std::vector<int> mittelwert, std::vector<int> varianz)
    {
      float ret_val = 0;
      for( ... )
        ret_val += ...
    
      return ret_val;
    }
    
    int main()
    {
      auto mittelwerte = give_vector( "mittelwert 1...n" );
      auto varianzen = give_vector( "varianz 1...n" );
    
      if(mittelwerte.size() != varianzen.size())
        std::cerr << "." << std::endl;
    
      auto f = integral_ausrechnen_mittels_trapzeregel( mittelwerte, varianzen );
      std::cout << "trapezregel sagt: " << f << std::endl;
    }
    

    den algo zur trapezregel kannst du sicherlich selbst irgendwie formulieren und zum funktionieren bringen...

    bb



  • Hallo,

    wow - vielen Dank für diesen Aufwand und deine Bemühungen 🙂

    Beste Grüße



  • eine Sache noch : die Funktion, die integriert wird, ist ja komplexwertig -- ist es sinnvoller (mittels Polarkorrd. etc) die Angelegenheit ins Reelle zu transformieren, oder mittels complex zu arbeiten?

    LG



  • Hallo Leute,

    complex<float>z(0,1);
    
    complex<float> funktion(std::vector<int>mw, std::vector<int>var) // hier soll die char. Fkt. entstehen.
    {
    	float t;
    	complex<float> y;
    
    	for(int l=0; l<mw.size();l++)
    	{
    		y *= (1/sqrt(1-2*z*var[l]*t));	
    	}
    	return y;
    }
    

    und zwar sollte hier mal sowas wie : l=1dimmittelwertvek112iσlt\prod_{l=1}^{dim mittelwertvek} \frac{1}{\sqrt{1-2i \sigma_{l}t}} gebastelt werden, aber da erhält man folgende Fehler:

    In function 'std::complex<float> funktion(std::vector<int>, std::vector<int>)':
    no match for 'operator*' (operand types are 'int' and 'std::complex<float>')

    etc --muss man hier auf so Dinge achten , wie etwa, dass mit Real und Imaginärteilt entsprechend multipliziert wird ?

    Danke für etwaige Antworten 🙂

    LG

    EDIT : Hat sich erledigt -- es werden einfach double Werte benötigt !


Log in to reply