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..
(Das wäre eigentlich dein Part gewesen.) 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
Mirco99
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 11.03.2009, 17:07
Titel:
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.
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.
Mirco99
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 12.03.2009, 11:33
Titel:
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?
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:
%%% 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']);
%%% =======================================================================
%%% 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
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: ---
Verfasst am: 12.03.2009, 15:12
Titel:
Kann mir nochmal jemand helfen??? Bei Erfolg kaufe ich ihm/ihr eine Kiste Bier....
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 ;)
Mirco99
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 12.03.2009, 18:14
Titel:
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 );
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!
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....
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.
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
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.