komplexe Übertragungsfunktion



  • Keine Ahnung wie du da
    'int' kann nicht in 'komplexeZahl' konvertiert werden
    bekommst. Bei mir funktionierts mit den Zeilen die ich oben geschrieben habe (also zumindest kompilierts und es kommt was raus, ob die Werte stimmen musst du selbst beurteilen):

    http://codepad.org/WKH2IqVF



  • Danke, also des Problem glaub ich liegt grad am Compiler...i probiers mal mit nem anderen...



  • Sodala, also mit nem anderem Compiler gehts nun bei mir auch. Ich hab nun folgendes... (Amp, Phase sind ausgerechnet) Umrechnung in dB für Grafik erst mal noch Nebensache, da ich des erst die Sache mit der Grafik kapieren muss 🙂

    #include <stdio.h>
    #include <math.h>
    
    //Vorgegebene Werte:
    const double C1 = 4e-12;
    const double C2 = 10e-12;
    const double L = 0.1e-3;
    const double R = 470;
    
    //Implementieren von Omega
    double omega;
    
    //Definition einer Komplexen Zahl
    struct komplexeZahl {
        double Re;
        double Im;
    };
    
    //Funktionsprototypen
    struct komplexeZahl H(double omega);
    double Amplitude (struct komplexeZahl h);
    double Winkel (struct komplexeZahl h);
    
    int main (void){
        struct komplexeZahl h;
    
        for (omega = 4.5e6; omega < 4.5e6 + 70 * 20e3;  omega = omega + 20e3) {
    
        h = H(omega);
    
        double Amp = Amplitude(h);
        double Pha = Winkel(h);  
    
        printf("%lf\n", Amp);
        }
    
        getchar();
        return 0;
    }
    
    //Funktion für Berechnung
    struct komplexeZahl H(double omega) {
    
        //Implementieren und berechnen von Leitwert
        struct komplexeZahl Y;
        Y.Re = 0;
        Y.Im = omega*(C2/(1-omega*omega*L*C2)-C1);
    
        //Implementieren von Zähler und Nenner 
        struct komplexeZahl u1,u2;
    
        //R*Y
        u2.Re = R * Y.Re;
        u2.Im = R * Y.Im;
    
        //1+R*Y
        u1.Re = 1 + u2.Re;
        u1.Im = u2.Im;
    
        //Die Division
        struct komplexeZahl h;
        h.Re = (u2.Re * u1.Re - u2.Im * u1.Im) / (u1.Im * u1.Im + u2.Im * u2.Im);
        h.Im = (u2.Re * u1.Im - u2.Im * u1.Re) / (u1.Im * u1.Im + u2.Im * u2.Im);
    
        return h;
    }
    
    //Funktion zum Berechnen der Amplitude
    double Amplitude (struct komplexeZahl h) {
           double Amp = sqrt((h.Im * h.Im) / (h.Re * h.Re));
           return Amp;
           }
    
    //Funktion zum Berechnen des Winkels
    double Winkel (struct komplexeZahl h) {
           double Pha = atan2(h.Im, h.Re);
           return Pha;
           }
    

    Jetzt soll ich das Ganze als 'Pseudo' Grafik darstellen:

    http://s1.directupload.net/images/111213/temp/bybewc5y.jpg

    Liege ich richtig in der Annahme, dass das in C nur über Schleifen und printf zu realisieren ist. Würde mich sehr freuen wenn ihr mir wieder helfen könntet. Ich mach mich morgen an meinen eigenen Ansatz, sollte ich eine zündende Idee haben, ansonsten bin ich wieder auf Euch angewiesen.

    So long... vielen Dank bisher und im Vorraus.

    scontch



  • Ich weiß nicht wie Kleinlich Dein Übungsgruppenleiter ist, aber in der Aufgabenstellung war explizit die Rede von Funktionen für die Grundrechenarten für Komplexe Zahlen. Evtl. solltest Du das noch nachholen und diese Funktionen dann für die Teilschritte der Berechnug verwenden.

    Tipp für die grafische Ausgabe:
    "Zeichne" zuerst in ein 2D-char-Array. Dort hast Du wahlfreien Zugriff was die Sache vereinfacht.

    Anschließend iterierst Du "von oben nach unten" über das Array und printest einfach jedes char in die Konsole.



  • Tipp für die grafische Ausgabe:
    "Zeichne" zuerst in ein 2D-char-Array. Dort hast Du wahlfreien Zugriff was die Sache vereinfacht.

    Anschließend iterierst Du "von oben nach unten" über das Array und printest einfach jedes char in die Konsole.

    Also mit 2D array kann ich mir das grad nicht Vorstellen bzw. kapier ich des ned. Ich hatte es mit nen normalen array probiert, aber das geht nur, wenn der erste Wert auch immer des Max. ist und der Letzte das Min.
    Dem ist aber leider nicht so. Der Graph sollte so aussehen.
    http://s7.directupload.net/file/d/2738/i7h7txz6_jpg.htm

    Bei Aufgabe 1 hat sich auch noch ein Problem ergeben, nachdem ich alles mit Funktionen gemacht habe.

    #include <stdio.h>
    #include <math.h>
    
    //Deklarieren der Variablen für die Kreisfrequenz
    double Pi = 3.141592654;
    double f;
    double omega;
    
    //Deklarieren der Variablen nach Vorgabe
    const double C1 = 4e-12, C2 = 10e-12, L = 0.1e-3, R = 470;
    
    //komplexe Zahl mit Real- und Imaginärteil deklarieren
    struct kompZ {
           double Re;
           double Im;
    };
    
    //Funktionsprototypen
    struct kompZ kAddition (struct kompZ kompZ1, struct kompZ kompZ2);
    struct kompZ kMultiplikation (double Zahl1, struct kompZ kompZ2);
    struct kompZ kDivision (struct kompZ kompZ1, struct kompZ kompZ2);
    double Phase (struct kompZ kompZ1);
    double Betrag (struct kompZ kompZ1);
    struct kompZ kLeitwert (double omega);
    struct kompZ H (struct kompZ y);
    
    int main()
    {
        for(f = 4.5e6; f <= 4.5e6 + 70 * 20e3; f = f + 20e3) {
    
    	omega = 2 * Pi * f;
    
    	struct kompZ y;
    	y = kLeitwert(omega);
    	printf("%lf + I %lf\n", y.Re, y.Im);
    
    	struct kompZ h;
    	h = H(y);
    	printf("H(%lf): %lf + I %lf\n\n\n", omega, h.Re, h.Im);
    
    	}
    
      	system("PAUSE");	
      	return 0;
    }
    
    //Funktion für die komplexe Addidion nach math. Regeln
    struct kompZ kAddition (struct kompZ kompZ1, struct kompZ kompZ2) {
           struct kompZ Erga;
           Erga.Re = kompZ1.Re + kompZ2.Re;
           Erga.Im = kompZ1.Im + kompZ2.Im;
           return Erga;
    }
    
    //Funktion für die komplexe Multiplikation mit einem Faktor nach math. Regeln
    struct kompZ kMultiplikation (double Zahl1, struct kompZ kompZ2) {
           struct kompZ Ergm;
           Ergm.Re = Zahl1 * kompZ2.Re;
           Ergm.Im = Zahl1 * kompZ2.Im;
           return Ergm;
    }
    
    //Funktion für die komplexe Division nach math. Regeln
    struct kompZ kDivision (struct kompZ kompZ1, struct kompZ kompZ2) {
           struct kompZ Ergd;
           Ergd.Re = (kompZ1.Re * kompZ2.Re - kompZ1.Im * kompZ2.Im) / (kompZ2.Re * kompZ2.Re - kompZ2.Im * kompZ2.Im);
           Ergd.Im = (kompZ1.Im * kompZ2.Re - kompZ1.Re * kompZ2.Im) / (kompZ2.Re * kompZ2.Re - kompZ2.Im * kompZ2.Im);
           return Ergd;
    }
    
    //Funktion für die Berechnung des Winkels von komplexen Zahlen nach math. Regeln
    double Phase (struct kompZ kompZ1) {
           double Pha;
           Pha = atan2(kompZ1.Im, kompZ1.Re);
           return Pha;
    }
    
    //Funktion für die Berechnung des Betrags einer komplexen Zahl nach math. Regeln
    double Betrag (struct kompZ kompZ1) {
           double Amp;
           Amp = sqrt ( kompZ1.Im * kompZ1.Im + kompZ1.Re * kompZ1.Re);
           return Amp;
    }
    
    //1. Berechnung des komplexen Leitwerts
    struct kompZ kLeitwert (double omega) {
           struct kompZ y;
           y.Re = 0;
           y.Im = omega * (C2 / (1 - omega * omega * L * C2) - C1);
           return y;
    }
    
    //2. Berechnung der Übertragungsfunktion 
    struct kompZ H (struct kompZ y) {
    
          //R * kLeitwert
          struct kompZ u2;
          u2 = kMultiplikation(R,y);
    
           //1 + R * kLeitwert
           struct kompZ u1;
           struct kompZ eins;
                  eins.Re = 1;
                  eins.Im = 0;
           u1 = kAddition ( eins , kMultiplikation ( R , y));
    
           struct kompZ h = kDivision (u2, u1);
    
           return h;
           }
    

    kLeitwert (also y) wird noch richtig ausgerechnet, aber H(y) dann leider nicht mehr. Das lässt ja nur den Schluss zu, dass in einer der Funktionen für Addidion, Multiplikation oder Division der Fehler liegen muss, finde dort aber keinen!!

    Hier noch der Vergleich des Programms mit der Berechnung, die Maple ausspuckt:

    http://s7.directupload.net/file/d/2738/5tjs3d7e_jpg.htm

    lg scontch



  • scontch schrieb:

    Also mit 2D array kann ich mir das grad nicht Vorstellen bzw. kapier ich des ned.

    Jeder Eintrag in dem 2D-Array entspricht einem "Pixel" auf dem Ausgabegerät. Du brauchst also sowas in der Art: char a[70][20]

    Der Vorteil ist folgender: Wenn Du die Kurve zeichnest und ein Sternchen an die Position x,y zu zeichnen hast, kannst Du einfach auf das Array zugreifen: a[x][y] = '*'. Das ist in der Console nicht ohne weiters möglich.

    Anschließend mit zwei Schleifen drüber laufen und alles auf einen Schlag printen.



  • In kDivision bei der Berechnung von Ergd.Re muss es ein + statt - sein



  • Vielen Dank fürs drüber schauen. Den Fehler hätt ich heute nicht mehr gefunden 😉

    Nach dem Frühstück mach ich mir mal nochmal Gedanken zu dem array...



  • dringendes Problem, bitte um schnelle antworten wenn möglich.

    #include <stdio.h>
    
    int main (void) {
    
    	int Bild [1] [1];
    	int i,j;
    
    	Bild [0][0] = '*';
    	Bild [1][0] = '*';
    
    	for (i=0;i<=1;i++){
    		for (j=0;j<=1;j++){
    	if (Bild [i][j] == '*'){
    	printf("*");
    }
    else{
    printf("1");
    }}}
    	getchar();
    	return 0;
    }
    

    ich erwarte bei der ausgabe 2 * erhalte aber 3, wieso?
    wenn ich die sternchen in [0] [0] und [1] [1] befülle erhalte ich korrekterweise 2. Wo is der Fehler??



  • Wieviele Elemente hat das Array Bild?



  • Also das Orginal zur Aufgabe soll 70 breit und 20 hoch sein;

    mein beispiel hab ich gelöst.
    ich hab null plan was ich mit der aufgabe machen soll, dass das ein richtiges bild wird.

    das is was ich hab. das bild stimmt null und ich weiss ned warum. wenn ich alles logisch durchgehe sollte es meiner meinung nach passen 😢

    #include <stdio.h>
    #include <math.h>
    
    //Deklarieren der Variablen für die Kreisfrequenz
    double Pi = 3.141592654;
    double f;
    double omega;
    
    //Deklarieren der Variablen nach Vorgabe
    const double C1 = 4e-12, C2 = 10e-12, L = 0.1e-3, R = 470;
    
    //komplexe Zahl mit Real- und Imaginärteil deklarieren
    struct kompZ {
    double Re;
    double Im;
    };
    
    //Funktionsprototypen
    struct kompZ kAddition (struct kompZ kompZ1, struct kompZ kompZ2);
    struct kompZ kMultiplikation (double Zahl1, struct kompZ kompZ2);
    struct kompZ kDivision (struct kompZ kompZ1, struct kompZ kompZ2);
    double Phase (struct kompZ kompZ1);
    double Betrag (struct kompZ kompZ1);
    struct kompZ kLeitwert (double omega);
    struct kompZ H (struct kompZ y);
    double log10(double x);
    double min_max (double AmpdB);
    
    int main()
    {
    
    double temp;
    double max = 20 * log10(Betrag(H(kLeitwert(2 * Pi * 4.5e6))));
    double min = max;
    
    double AmpdBtemp [70];
    int t = 0;
    
    for(f = 4.5e6; f <= 4.5e6 + 70 * 20e3; f = f + 20e3) {
    
    omega = 2 * Pi * f;
    
    struct kompZ y;
    y = kLeitwert(omega);
    
    struct kompZ h;
    h = H(y);
    
    double Amp = Betrag(h);
    double Pha = Phase(h);
    
    //printf("Omega: %lf\tAmpltiude: %lf\tPhase:%lf\n",omega,Amp,Pha);
    
    double AmpdB = 20* log10(Amp);
    //printf("AmpdB: %lf\n\n", AmpdB);
    
    temp = AmpdB;
    
    if (max < temp) {
    max = temp;
    }
    
    if (min > temp) {
    min = temp;
    }
    
    AmpdBtemp [t] = AmpdB;
    t++;
    
    }
    /*
    int penis;
    for (penis=0; penis<70; penis++)
    printf ("%f\n", AmpdBtemp[penis]);
    *///Array AmpdBtemp wird richtig befüllt
    
    double step = (min - max) / 20;
    
    char Bild [70] [20];
    double point0 = min;
    double point1;
    int i, j=0;
    
    Bild [0] [0] = '*';
    t = 0;
    for (i = 1; i < 70; i++) {
    point1 = AmpdBtemp [t];
    t++;
    
    if (point1 > point0) {
    
    if (point1 - point0 > step ) {
    Bild [i] [j+1] = '*';
    point0 = point1;
    j++;
    }
    
    else {
    Bild [i] [j] = '*';
    point0 = point1;
    }
    }
    
    else {
    
    if (point0 - point1 > step) {
    Bild [i] [j-1] = '*';
    point0 = point1;
    j--;
    }
    
    else {
    Bild [i] [j] = '*';
    point0 = point1;
    }
    }
    }
    
    int x;
    int y;
    
    for (y = 0; y < 19; y++) {
    
    for (x = 0; x < 70 ; x++){ 
    if (Bild [x][y] == '*') 
    printf("*");
    else
    {printf (" ");}
    }
    printf("\n");
    
    }
    
    system("PAUSE");	
    return 0;
    }
    
    //Funktion für die komplexe Addidion nach math. Regeln
    struct kompZ kAddition (struct kompZ kompZ1, struct kompZ kompZ2) {
    struct kompZ Erga;
    Erga.Re = kompZ1.Re + kompZ2.Re;
    Erga.Im = kompZ1.Im + kompZ2.Im;
    return Erga;
    }
    
    //Funktion für die komplexe Multiplikation mit einem Faktor nach math. Regeln
    struct kompZ kMultiplikation (double Zahl1, struct kompZ kompZ2) {
    struct kompZ Ergm;
    Ergm.Re = Zahl1 * kompZ2.Re;
    Ergm.Im = Zahl1 * kompZ2.Im;
    return Ergm;
    }
    
    //Funktion für die komplexe Division nach math. Regeln
    struct kompZ kDivision (struct kompZ kompZ1, struct kompZ kompZ2) {
    struct kompZ Ergd;
    Ergd.Re = (kompZ1.Re * kompZ2.Re - kompZ1.Im * kompZ2.Im) / (kompZ2.Re * kompZ2.Re + kompZ2.Im * kompZ2.Im);
    Ergd.Im = (kompZ1.Im * kompZ2.Re - kompZ1.Re * kompZ2.Im) / (kompZ2.Re * kompZ2.Re + kompZ2.Im * kompZ2.Im);
    return Ergd;
    }
    
    //Funktion für die Berechnung des Winkels von komplexen Zahlen nach math. Regeln
    double Phase (struct kompZ kompZ1) {
    double Pha;
    Pha = atan2(kompZ1.Im, kompZ1.Re);
    return Pha;
    }
    
    //Funktion für die Berechnung des Betrags einer komplexen Zahl nach math. Regeln
    double Betrag (struct kompZ kompZ1) {
    double Amp;
    Amp = sqrt ( kompZ1.Im * kompZ1.Im + kompZ1.Re * kompZ1.Re);
    return Amp;
    }
    
    //1. Berechnung des komplexen Leitwerts
    struct kompZ kLeitwert (double omega) {
    struct kompZ y;
    y.Re = 0;
    y.Im = omega * (C2 / (1 - omega * omega * L * C2) - C1);
    return y;
    }
    
    //2. Berechnung der Übertragungsfunktion 
    struct kompZ H (struct kompZ y) {
    
    //R * kLeitwert
    struct kompZ u2;
    u2 = kMultiplikation(R,y);
    
    //1 + R * kLeitwert
    struct kompZ u1;
    struct kompZ eins;
    eins.Re = 1;
    eins.Im = 0;
    u1 = kAddition ( eins , kMultiplikation ( R , y));
    
    struct kompZ h = kDivision (u2, u1);
    
    return h;
    }
    


  • Bitte rück deinen Code doch vernünftig ein, das ist ja extrem schwierig zu lesen so...
    Aber ich verstehe die Logik auch nicht. Wieso machst du nicht einfach:

    double AmpdBtemp[70];
    char Bild [70] [20];
    int maxdB,mindB;
    
    /* Berechne AmpdBtemp und die maximal und minimalwerte maxdB und mindB
       [...]*/
    
    /* Initialisiere Bild mit ' '
       [...]*/
    
    for (int i=0; i<70; i++)
    {
      int dBValue=(int)((AmpdBtemp[i]-mindB)/(maxdB-mindB)*20); /*Rechne das nochmal nach, damit das auch stimmt*/
      Bild[i][dBValue]='*';
    }
    
    /* Hier Bild ausgeben
       [...]*/
    


  • Meine Logik dahinter war das "dynamische Befüllen des Arrays", da die dritte Aufgabe ist, den Benutzer C1, C2, L und R auswählen zu lassen und dann die Grafik anzupassen. Kann ich des dann auch so machen?

    /* Initialisiere Bild mit ' '
    [...]*/

    Hmm, heißt das, ich soll einfach das ganze Array mit Leerzeichen befüllen, oder wie war des gemeind?

    Sorry für den unübersichtlichen Code. War müde und der Kopf war voll. Der nächste ist Vorbildlich 🙂



  • Hier ein Stückchen Code, das das Ausgeben übernimmt. So einfach wie möglich geschrieben (das ginge sowohl effizienter als auch schöner...). Ich hoffe so wird die Idee klar:

    #include <stdio.h>
    #include <math.h>
    
    int main(void)
    {
      char image[10][11];
      int values[]={1,2,3,4,3,2,1,1,0,5};
      int i=0,j=0;
    
      // Mit ' ' füllen
      for (i=0; i<10; i++)
      {
        for (j=0; j<10; j++)
        {
          image[i][j]=' ';
        }
        image[i][10]=0;
      }
    
      // Zeichnen
      for (i=0; i<10; i++)
      {
        image[values[i]][i]='*';
      }
    
      // Ausgeben
      for (i=9; i>=0; i--)
      { 
        printf("%s\n",image[i]);
      }
    
      return 0;
    }
    


  • Hi, ja hab zwar lange gebraucht, aber ich denke so einigermaßen hab ichs überrissen.

    Vielen vielen Dank 🙂

    Dennoch hab ich noch 2, 3 Probleme 😃

    Also folgendes hab ich bisher:

    int main()
    {
     	//Implementieren der Variablen zur Berechnung von Minimum und Maximum
    	double temp;
     	double max = 20 * log10(Betrag(H(kLeitwert(2 * Pi * 4.5e6))));
    	double min = max;
    
    	//Array zur Speicherung der Ergebnisse in dB 
        int AmpdBtemp [70];
     	int t = 0;
    
        //Berechnung der 70 Stützwerte
    	for(f = 4.5e6; f <= 4.5e6 + 70 * 20e3; f = f + 20e3) {
    
    		  omega = 2 * Pi * f;
    
    		  struct kompZ y;
    		  y = kLeitwert(omega);
    
     		  struct kompZ h;
    		  h = H(y);
    
    		  double Amp = Betrag(h);
    		  double Pha = Phase(h);
    		  double AmpdB = 20* log10(Amp);
    
    		  temp = max;
    
    		  	  if (max < temp) {
    			  	 max = temp;
    			  }
    
    			  if (min > temp) {
    			  	 min = temp;
    			  }
    
    		AmpdBtemp [t] = AmpdB * (-1);
    		t++;
    	}
    
     	char Bild[70][71]; 
      	int i=0,j=0; 
    
        // Komplettes Bild mit Leerzeichen füllen 
      	for (i=0; i<70; i++) {
      		for (j=0; j<70; j++) { 
          		Bild[i][j]=' '; 
      		} 
        	Bild[i][70]=0; 
    	} 
    
     	// Im Array 'zeichnen' 
      	for (i=0; i<70; i++) {
      	  int dBValue=((AmpdBtemp[i]-min)/(max-min)*20);
    	  Bild[AmpdBtemp[i]][dBValue]='*'; 
        } 
    
       	// Ausgeben 
      	for (i=0; i<=69; i++) {
      		printf("%s\n",Bild[i]); 
        } 
    
      	system("PAUSE");	
      	return 0;
    }
    

    Zum einen muss bei mir bei

    int Bild [70][71]
    

    egal mit welchen Werten, der zweite immer eins höher sein als der erste. sonst funktionierts nicht. Aber dann hab ich ja so viele Zeilen, aber ich will ja nur 20. Geb ich da aber eine 20 rein, gibts keine Ausgabe mehr.

    Zum anderen funktioniert

    int dBValue=((AmpdBtemp[i]-min)/(max-min)*20);
    	  Bild[AmpdBtemp[i]][dBValue]='*';
    

    nicht 😞 ohne die Berechnung und mit

    Bild[AmpdBtemp]][i]
    

    klappts.
    Will ich auf 20 "dehnen" stürzt mir das Programm ab.

    Und was mich noch intressehalber interessiert: wieso bekomm ich Smileys oder andere Symbole aus der ASCII Tabelle wenn ich die letzte Zeile nicht 0 setze?



  • scontch schrieb:

    Zum einen muss bei mir bei

    int Bild [70][71]
    

    egal mit welchen Werten, der zweite immer eins höher sein als der erste. sonst funktionierts nicht. Aber dann hab ich ja so viele Zeilen, aber ich will ja nur 20. Geb ich da aber eine 20 rein, gibts keine Ausgabe mehr.

    Komm schon Mann. Mach mal die Augen auf:

    for (i=0; i<70; i++) {
    for (j=0; j<70; j++) {



  • ja schon klar, aber wenn des angepasst is gehts auch nicht. dann gibt er kauderwelsch aus. aber egal. ich kanns ja bei der ausgabe auf 20 zeilen kürzen.

    Allerdings funktioniert das "ziehen" auf 20 zeilen nicht..


Anmelden zum Antworten