WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Rechteckfunktion

 

Mirco99

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 11.03.2009, 15:19     Titel: Rechteckfunktion
  Antworten mit Zitat      
Hallo, ich suche Hilfe zu einer Matlab-Funktion, kenne das Programm erst seit wenigen tagen und habe auch mathematisch einigen Nachholbedarf....

Ich möchte eine sogenannte Rechteckwelle darstellen. Bislang habe ich dafür folgenden MatLab-Code:

" e = sin( freq/1.79*3*pi*time/max(time) );
e( find(e<0) ) = 0;
e( find(e>0) ) = 1;
e = (amp-ped) * e + ped;"

freq ist die Frequenz z.B. 3
amp ist die Obergrenze
ped ist die Untergrenze

Ich möchte gerne die "Rechtecke" dieser Sinusfunktion unterschiedlich groß machen. Geht das überhaupt mit einer Sinusfunktion? Wenn ja, wie könnte ich es definieren? Desweiteren würde ich auch gerne unterschiedliche Obergrenzen und Untergrenzen definieren, ist aber erstmal zweitrangig.

Den kompletten Code habe ich als Anhang angehängt..

Gruss und danke für Hilfe

Mirco

BlackForest_Pollen.m
 Beschreibung:

Download
 Dateiname:  BlackForest_Pollen.m
 Dateigröße:  4.31 KB
 Heruntergeladen:  625 mal


Bijick
Ehrenmitglied

Ehrenmitglied



Beiträge: 914
Anmeldedatum: 18.06.07
Wohnort: Nürnberg
Version: R2006b, R2008b
     Beitrag Verfasst am: 11.03.2009, 16:49     Titel:
  Antworten mit Zitat      
Hallo Mirco,

ich habe mal den wesentlichen Code herausgeschnitten:

Code:
amp  = 15;
freq = 2;
ped  = 22;

timestep = 10;
maxtime  = 10e4;
time     = timestep:timestep:maxtime;

e = sin(freq/1.79*3*pi*time/max(time));
e(e<0) = 0;
e(e>0) = 1;
e = (amp-ped) * e + ped;
e = 1e2/1e6 * e; % m/Myrs to cm/yrs
e = e * timestep;

plot(time,e)


(Das wäre eigentlich dein Part gewesen.) Smile Die Breite der Rechtecke kannst Du über freq steuern, die Höhe über amp und die Verschiebung auf der y-Achse über ped. Probier in meinem Code einfach mal verschiedene Werte für die drei Variablen aus und schau Dir die Graphen an.

Herzliche Grüße
Bijick

P. S.: Ich habe mal den Titel etwas aussagekräftiger gemacht.
_________________

>> why
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
Mirco99

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 11.03.2009, 17:07     Titel:
  Antworten mit Zitat      
Hallo Bijick,

danke für die schnelle Antwort. Ich glaube aber ich habe mich falsch ausgedrückt. Ich möchte, dass die Rechtecke verschiedengroße y-Werte erhalten. Also dass das erste Rechteck eine x-Länge von 1500 hat und das nächste Rechteck dagegen beispielsweise 4500. Ich möchte also von der strikten Gleichförmigkeit der Sinuskurve wegkommen. So dass man eventuell einem Rechteck einen definierten Bereich auf der x-Achse zuweisst...
Und dann entsprechend sich auch die y-Höhe zwischen den Rechtecken unterscheidet und nicht gleich groß ist für die jeweiligen Rechtecke.

Beispiel.JPG
 Beschreibung:

Download
 Dateiname:  Beispiel.JPG
 Dateigröße:  1.87 KB
 Heruntergeladen:  537 mal
 
Epfi
Forum-Meister

Forum-Meister



Beiträge: 1.134
Anmeldedatum: 08.01.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 11.03.2009, 18:06     Titel:
  Antworten mit Zitat      
Definier Dir doch eine Funktion, die so aussieht:

Code:

                             __________
                            |          |
                            |          |
      _______               |          |
     |       |              |          |
     |       |              |          |
_____|       |______________|          |________________


Die Funktion hat die gleiche Abtastrate wie dein Rechtsignal und ist genau so lang. Die multiplizierst Du elementweise (.*) mit deinem Rechtecksignal und schon hast Du verschiedene Amplituden.
Private Nachricht senden Benutzer-Profile anzeigen
 
Mirco99

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.03.2009, 11:33     Titel:
  Antworten mit Zitat      
Danke für den Tip, aber ich gleube Mathe ist zu lange her mit mir. Ich komme auf keine gescheite Funktion. Hat ein Mathematiker unter euch einen Ansatz/Tip für mich wie ich so eine Funktion definiere?
 
Epfi
Forum-Meister

Forum-Meister



Beiträge: 1.134
Anmeldedatum: 08.01.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.03.2009, 11:41     Titel:
  Antworten mit Zitat      
Das schöne an Matlab ist, dass Du die Punkte auch direkt vorgeben kannst. Das Gebilde muss nicht als ein Stück Formel darstellbar sein (wobei das durchaus möglich, aber auch sehr, sehr länglich wäre). Im prinzip hast Du eine abschnittsweise konstante Funktion:

Code:

rechteck(0:2/samplezeit) = 0; %0...2s -> 0
rechteck(2/samplezeit:5/samplezeit) = 1; %2...5s -> 1
rechteck(5/samplezeit:8/samplezeit) = 0; %5...8s -> 0
rechteck(8/samplezeit:12/samplezeit) = 3; %5...8s -> 3
...
rechteck(x/samplezeit:length(ursprüngliche_funktion)) = 0; %x...ende -> 0
 


Wobei samplezeit der Zeitabstand (in Sekunden) zwischen zwei Punkten deiner ursprünglichen Funktion ist.
Private Nachricht senden Benutzer-Profile anzeigen
 
Mirco99

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.03.2009, 12:36     Titel:
  Antworten mit Zitat      
Danke für den Tip, bekomme allerdings ein paar Fehlermeldungen, die ich nicht verstehe:

Code:
function[concentration] = erode( flag, AMPLITUDE, FREQUENCY, PEDESTAL, ATLANTICBOREAL, ANTHROPOGEN, RECENT  );

%%% DEFAULT PARAMETERS OF PERIODIC EROSIONS
%%%
if( ~exist( 'AMPLITUDE' ) ) AMPLITUDE = 150; end;
if( ~exist( 'FREQUENCY' ) ) FREQUENCY = 2; end;
if( ~exist( 'PEDESTAL' ) ) PEDESTAL = 22; end;
if( ~exist( 'ATLANTICBOREAL' ) ) ATLANTICBOREAL = 22; end;
if( ~exist( 'ANTHROPOGEN' ) ) ANTHROPOGEN = 150; end;
if( ~exist( 'RECENT' ) ) RECENT = 22; end;

%%% VARIOUS CONSTANTS
%%%
flag = 4;
timestep = 10;      % time step - this times the below defines the timestep
                  % for high erosion rates, lower the time step
maxtime  = 10e4;         % max time - sets the run duration of the model
time     = [timestep : timestep : maxtime];   % time interval

P0       = 17*timestep;         % surface production
C0       = 100;           % initial concentration
mu       = 2.65/165;   % constant
lambda   = log(2)/1.5e6 * timestep;% decay rate
e        = erosionrate( flag, time, AMPLITUDE, FREQUENCY, PEDESTAL, ATLANTICBOREAL, ANTHROPOGEN, RECENT );
e        = 1e2/1e6 * e; % m/Myrs to cm/yrs
e        = e * timestep;

%%% ERODE IT...
%%%
%%%100 sets the sample interval for the data - reduce for finer resolution
ttt = 1 : 1 : length(time);
concentration = zeros( 1, length(ttt) );
count = 1;
for t = ttt
   C = C0;
   CS = fliplr( cumsum( fliplr(e(1:t)) ) );
   for k = 1 : t
      c = P0 * exp(-mu*CS(k)) - lambda*C;
      C = C + c;
   end
   concentration(count) = C;
   count = count + 1;
end

%%% ESTIMATE EROSION FROM ASSUMED STEADY-STATE CONCENTRATION
%%%
eEst = P0 ./ (concentration*mu) -lambda;
eEst = eEst/timestep * 1e6/1e2;


%%% PLOT EVERYTHING
%%%
set( gca, 'FontSize', 12 );
subplot(211); plot( time(ttt), concentration, 'bo-' );
xlabel( 'Time (y)' );
ylabel( '^{10}Be (atoms/gram)' );
set( gca, 'xlim', [1e3 maxtime]);
set( gca, 'ylim', [10 2e5] );         %change this to reflect expected max concentration
grid on;
subplot(212); plot( time(ttt), e(ttt)/timestep*1e6/1e2, 'r' );
hold on;
plot( time(ttt), eEst, 'k--' );
hold off;
%set( gca, 'Xscale', 'log' );
xlabel( 'Time (y)' );
ylabel( 'Erosion (m/My)' );
set( gca, 'xlim', [1e3 maxtime] );      %change this to 1e5 when time is >10^6 yrs-1e2 otherwise
set( gca, 'ylim', [10 4e2] );            %change this to be just over the max erosion
format long;
disp( [time(ttt)' concentration' e(ttt)'/timestep*1e6/1e2 eEst'] );


return;

%%% =======================================================================
%%% DEFINE ERORSION RATE AS A FUNCTION OF TIME
%%%
function[e] = erosionrate( flag, time, amp, freq, ped, atl, ant, rec )
   
   if( flag == 1 ); % zero (steady state)
      e = zeros(size(time));
   elseif( flag == 2 ) % constant
      e = amp * ones(size(time));
   elseif( flag == 3 ) % full-wave rectification
      e = sin( freq*2*pi*time/max(time) );
      e(find(e<0)) = 0;
     e = (amp-ped) * e + ped;
   elseif( flag == 4 ) % square-wave
      rechteck(0:2/29) = 0; %0...2s -> 0
      rechteck(2/29:5/41) = 1; %2...5s -> 1
      rechteck(5/41:8/78.6) = 0; %5...8s -> 0
      rechteck(8/78.6:12/89.5) = 3; %5...8s -> 3
      rechteck(x/0:length(e)) = 0; %x...ende -> 0
      e = sin( freq/1.79*3*pi*time/max(time) );
      e( find(e<0) ) = 0;
      e( find(e>0) ) = 1;
     e = (amp-ped) * e + ped;
   elseif( flag == 5 ) % saw-tooth
      N = length(time);
      n = N / freq;
      saw = [1:n]/n;
      e = repmat( saw, 1, freq );
      e = (amp-ped) * e + ped;
      if( length(e)<N ) % freq is a non-integer multiple of time
       e( length(e)+1:N ) = e(1:N-length(e));
      end
   elseif( flag == 6 ) % exponential
      N = length(time);
      n = N / freq;
      expo = exp(-([n:-1:1]/n)*6);
      e = repmat( expo, 1, freq );
      e = (amp-ped) * e + ped;
      if( length(e)<N ) % freq is a non-integer multiple of time
       e( length(e)+1:N ) = e(1:N-length(e));
      end
   elseif( flag == 7 ) % step
      N = length(time);
      n = round(N/1.5);
      e = zeros( 1,n );
      e( length(e)+1:N ) = 1;
     e = (ped-amp) * e + amp;
   elseif( flag == 8 ) % constant
      e = amp * ones(size(time));
   else
      fprintf( 'erosionrate(): invalid flag (%d)-using steady state\n', flag );
      e = zeros(size(time));
   end
 


Fehlermeldung:

Warning: Integer operands are required for colon operator when used as index
> In BlackForest_Pollen>erosionrate at 103
In BlackForest_Pollen at 38
??? Subscript indices must either be real positive integers or logicals.

Error in ==> BlackForest_Pollen>erosionrate at 103
rechteck(0:2/29) = 0; %0...2s -> 0

Error in ==> BlackForest_Pollen at 38
e = erosionrate( flag, time, AMPLITUDE, FREQUENCY, PEDESTAL, ATLANTICBOREAL, ANTHROPOGEN,
RECENT );
 
Mirco99

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.03.2009, 15:12     Titel:
  Antworten mit Zitat      
Kann mir nochmal jemand helfen??? Bei Erfolg kaufe ich ihm/ihr eine Kiste Bier....

Bidde Smile
 
Epfi
Forum-Meister

Forum-Meister



Beiträge: 1.134
Anmeldedatum: 08.01.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.03.2009, 17:39     Titel:
  Antworten mit Zitat      
Oh, das ist ne günstige Kiste!

Code:

      rechteck(0:2/29) = 0;
      rechteck(2/29:5/41) = 1;
      rechteck(5/41:8/78.6) = 0;
      rechteck(8/78.6:12/89.5) = 3;
      rechteck(x/0:length(e)) = 0;
 


All die Brüche, die Du da ausrechnest liefern keine ganze Zahl. Der Index einer Matrix muss aber eine solche sein. Erfolg bringt dann der Befehl round, der die Zahl auf die nächste ganze Zahl rundet.

Samplezeit ist übrigens ein konstanter Wert und ist der zeitliche Unterschied zwischen zwei Punkten. Zum Beispiel bekommst Du diesen Wert durch time(2) - time(1) oder direkt aus der Variable timestep. Irgendwas stimmt also bei der Definition noch nicht so ganz. Der Nenner muss überall 10 sein. In den Zähler schreibst Du dann die Zeit in Sekunden.

PS: Die Kiste darfst Du selbst austrinken, wenn es läuft ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
Mirco99

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.03.2009, 18:14     Titel:
  Antworten mit Zitat      
HI,

mit dem Biertrinken dauert es wohl noch.....

habe ein wenig unmgeschrieben, passt aber immer noch nicht.
Ist time die richtige Variabel zum runden? Die Brüche müssten aber auch so ganze Zahlen ergeben, da timestep=10. Fehlermeldung lautet:

??? Subscript indices must either be real positive integers or logicals.

Error in ==> BlackForest_Pollen>erosionrate at 104
rechteck(0:29000/timestep) = 150; %0...2s -> 0

Error in ==> BlackForest_Pollen at 38
e = erosionrate( flag, time, timestep, AMPLITUDE, FREQUENCY, PEDESTAL, ATLANTICBOREAL,
ANTHROPOGEN, RECENT );




[code]round (time)
rechteck(0:29000/timestep) = 150; %0...2s -> 0
rechteck(29000/timestep:41000/timestep) = 1; %2...5s -> 1
rechteck(41000/timestep:79000/timestep) = 0; %5...8s -> 0
rechteck(79000/timestep:90000/timestep) = 3; %5...8s -> 3
rechteck(100000/0:length(e)) = 0; %x...ende -> 0
e = sin( freq/1.79*3*pi*time/max(time) );
e( find(e<0) ) = 0;
e( find(e>0) ) = 1;
e = (amp-ped) * e + ped;[code][/code]
 
spawnferkel
Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 53
Anmeldedatum: 11.03.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.03.2009, 18:20     Titel:
  Antworten mit Zitat      
Ein Fehler steck auf jeden Fall hier:
Code:
rechteck(0:29000/timestep) = 150; %0...2s -> 0

Indizes fangen bei 1 an, nicht bei 0.
Private Nachricht senden Benutzer-Profile anzeigen
 
Epfi
Forum-Meister

Forum-Meister



Beiträge: 1.134
Anmeldedatum: 08.01.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.03.2009, 18:28     Titel:
  Antworten mit Zitat      
spawnferkel hat Folgendes geschrieben:
Indizes fangen bei 1 an, nicht bei 0.

Mea culpa...

Grundsätzlich muss 29000/10 nicht unbedingt eine ganze Zahl ergeben. sin(pi) ist laut Matlab ja auch nicht null...


Code:

rechteck(0:29000/timestep) = 150; % --> Nicht bei null anfangen, sondern bei 1 (das ist die Fehlermeldung)
rechteck(100000/0:length(e)) = 0; % --> Nicht durch Null dividieren! Niemals!


Die letzte Zeile sollte vermutlich so lauten, oder?
Code:
rechteck(100000:length(e)) = 0;
Private Nachricht senden Benutzer-Profile anzeigen
 
Mirco99

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.03.2009, 18:38     Titel:
  Antworten mit Zitat      
Super!

Es wird. Er rechnet schon.... Allerdings kommt jetzt die Fehlermeldung, dass e nicht definiert ist. Aber e wird ja auch erst eine Zeile später errechnet, wie kann ich das verknüpfen.

Ich komme wie vor wie ein Baby welches laufen lernt....
 
Epfi
Forum-Meister

Forum-Meister



Beiträge: 1.134
Anmeldedatum: 08.01.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.03.2009, 18:41     Titel:
  Antworten mit Zitat      
Mirco99 hat Folgendes geschrieben:
Aber e wird ja auch erst eine Zeile später errechnet, wie kann ich das verknüpfen.


Gar nicht? Setz doch Berechnung des rechteck-vektors einfach unter die Berechnung von e. Nachdem Du e und rechteck hast kommt dann noch ein
Code:
e = e .* rechteck;
um die Amplitudenänderung auf e anzuwenden.
Private Nachricht senden Benutzer-Profile anzeigen
 
Mirco99

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.03.2009, 19:02     Titel:
  Antworten mit Zitat      
Es klappt nur ohne Fehlermeldung, wenn ich

Code:
e = e * rechteck


an das Ende setze. Aber die Rechtecke sind alle gleich groß und lassen sich überhaupt nicht verändern... Das sind auf einmal ganz viele und nicht mehr nur zwei INtervalle.

Oh Gott!!!
 
Neues Thema eröffnen Neue Antwort erstellen

Gehe zu Seite 1, 2  Weiter

Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.