I am working on a homework problem for a Matlab course. This is the problem :
Construct an m-file function mom that follows the flow diagram for the algorithm shown on slide 5. Notice that the output is given not to the screen but into a file called output.txt and also has a given structure (see slide 6).
In your script call this function with the following inputs (place these inputs into your script file as shown and then call the mom function as mom(x,r,name,filename);)
x = [1 3 2 5 3 3 7 4 3 4 5 8 2];
r = 4;
name = ‘Your name here’;
filename = ‘output.txt’;
mom(x,r,name,filename);
I am also attaching the algorithm flowchart and the output file structure.
My main script code looks like this:
x=[1 3 2 5 3 3 7 4 3 4 5 8 2 ];
r=4;
name= 'Matthew Haskell';
filename='output.txt';
[xbar,sn]=mom_Haskell(x,r,name,filename);
out= fopen('Output.txt','w');
fprintf(out,'\t\t\tCalculation by: %s\n\n',name);
fprintf(out,'The average is %.4f while the %.2f th moment is %.2f', xbar,r,sn);
My function file code looks like this:
function[xbar,sn] = mom_Haskell( x,r,name,filename )
n=length(x);
xbar=mean(x);
num=0;
den=0;
for k:1:1:n
num=num+(x(k)-xbar)^r;
den=den+(x(k)-xbar)^2;
end
sn=(num/n) / (den/n)^(r/2);
end
So far, I have encountered a problem with the function file and being able to output it from the main file. I believe there is a problem with the variable sn, I am not sure how to fix this.
The problem is in the syntax with the for-loop:
k=1:1:n
instead of
k:1:1:n
For the sake of completeness, it is worth knowing that if the step is 1, you can easily omit such step. So the instruction
k=1:1:n
is the same as
k=1:n
Also, according to the given specifications (second slide) the second fprintf() should be corrected as well. Such specifications says that:
xbar must have 4 decimal places, and %.4f is correct
r must be an integer, so %.4f is not correct. You need %d for integers
sn should be floating point with 6 decimal places, but %.2f will show a floating point with just 2 decimal place. Use %.6f instead.
Related
suppose that we are determine peaks in vector as follow:
we have real values one dimensional vector with length m,or
x(1),x(2),.....x(m)
if x(1)>x(2) then clearly for first point peak(1)=x(1);else we are then comparing x(3) to x(2),if x(3)
[ indexes,peaks]=function(x,m);
c=[];
b=[];
if x(1)>x(2)
peaks(1)=x(1);
else
for i=2:m-1
if x(i+1)< x(i) & x(i)>x(i-1)
peak(i)=x(i);
end;
end
end
end
peaks are determined also using following picture:
sorry for the second picture,maybe it is not triangle,just A and C are on straight line,but here peak is B,so i can't continue my code for writing algorithm to find peak values in my vector.please help me to continue it
updated.numercial example given
x=[2 1 3 5 4 7 6 8 9]
here because first point is more then second,so it means that peak(1)=2,then we are comparing 1 to 3,because 3 is more then 1,we now want to compare 5 to 3,it is also more,compare 5 to 4,because 5 is more then 4,then it means that peak(2)=5,,so if we continue next peak is 7,and final peak would be 9
in case of first element is less then second,then we are comparing second element to third one,if second is more then third and first elements at the same time,then peak is second,and so on
You could try something like this:
function [peaks,peak_indices] = find_peaks(row_vector)
A = [min(row_vector)-1 row_vector min(row_vector)-1];
j = 1;
for i=1:length(A)-2
temp=A(i:i+2);
if(max(temp)==temp(2))
peaks(j) = row_vector(i);
peak_indices(j) = i;
j = j+1;
end
end
end
Save it as find_peaks.m
Now, you can use it as:
>> A = [2 1 3 5 4 7 6 8 9];
>> [peaks, peak_indices] = find_peaks(A)
peaks =
2 5 7 9
peak_indices =
1 4 6 9
This would however give you "plateaus" as well (adjacent and equal "peaks").
You can use diff to do the comparison and add two points in the beginning and end to cover the border cases:
B=[1 diff(A) -1];
peak_indices = find(B(1:end-1)>=0 & B(2:end)<=0);
peaks = A(peak_indices);
It returns
peak_indices =
1 4 6 9
peaks =
2 5 7 9
for your example.
findpeaks does it if you have a recent matlab version, but it's also a bit slow.
This proposed solution would be quite slow due to the for loop, and you also have a risk of rounding error due to the fact that you compare the maximal value to the central one instead of comparing the position of the maximum, which is better for your purpose.
You can stack the data so as to have three columns : the first one for the preceeding value, the second is the data and the third one is the next value, do a max, and your local maxima are the points for which the position of the max along columns is 2.
I've coded this as a subroutine of my own peak detection function, that adds a further level of iterative peak detection
http://www.mathworks.com/matlabcentral/fileexchange/42927-find-peaks-using-scale-space-approach
I'm new to Simulink but I need to use a matlab function.
I created a "MATLAB Function1" block with one input (a time signal that comes from another block) and one output (three signals wrapped in a matrix shown in a Scope block).
Here the code inside the matlab function block:
function outputSignal = myFunction(input_signal)
coder.extrinsic('lsim');
time = [1:1:length(input_signal)];
k_dia = [19.5 13 9.9];
k_dia = k_dia*10^-3;
outputSignal = zeros(length(time), length(k_dia));
for j = 1:length(k_dia)
A = [-k_dia(j) 0; k_dia(j) -k_dia(j)];
B = [1 0]';
C = [1 1];
D = 0;
sistem = feval('ss', A, B, C, D);
outputSignal(:,j) = lsim(sistem, input_signal, time);
end
end
Previously I had problems using the functions "ss" and "lsim" because of code generation problems, but I should have solved them using feval and coder.extrinsic. Now I have the following error:
When simulating the response to a specific input signal, the input data U must be a matrix
of numeric values with at least two rows (samples) and without any NaN or Inf.
and I can't understand if the problem is still with these functions or if I made a mistake in how to use matlab functions in simulink.
EDIT: I understood that the problem was because lsim needs an input_signal of at least length 2, while my system is giving an input to the function of one single value at every time step. So if the time is of 10 steps and the serie of values generated from the previous block is [1 2 3 4 5 6 7 8 9 10], I would like to have as input to my function:
[1] at step 1,
[1 2] at step 2,
[1 2 3] at step 3,
....
[1 2 3 4 5 6 7 8 9 10] at step 10.
Of course since lsim doesn't work with one value, at step 1 I could use a default output value.
I think I need a block that memorizes what happens in the time steps
before, something like the Scope block but with an output.
Since your systems are time invariant you can create three separate State space systems each with different parameter valued matrices and supply a vector of three components as input signals which I have left empty because I don't know where you would like to send from.
Hello it`s my first post here. I want to write matlab script for Delaunay triangulation. Here is my script:
clear all;clc
%% Delaunay
x=[ 160.1671 366.9226 430.7894 540.1208 660.2771 508.7287 252.1787];
y=[ 223.9615 259.5000 120.5769 245.5000 283.1923 472.7308 469.5000];
%
x=x';
y=y';
%orginal plot
dd=delaunay(x,y);
dt=TriRep(dd,x,y);
triplot(dt);
z=[x.^2+y.^2]
i=1:length(x);
ptk=[i' x y]
%% main loop
l=0;
for i=1:length(x)-2
for j=1+i:length(x)
for k=1+i:length(x)
if (j ~= k)
l=l+1;
xn = (y(j)-y(i))*(z(k)-z(i)) - (y(k)-y(i))*(z(j)-z(i));
yn = (x(k)-x(i))*(z(j)-z(i)) - (x(j)-x(i))*(z(k)-z(i));
zn = (x(j)-x(i))*(y(k)-y(i)) - (x(k)-x(i))*(y(j)-y(i));
if (zn < 0)
border=zn;
for m=1:length(x)
border = (border) & ...
((x(m)-x(i))*xn +...
(y(m)-y(i))*yn +...
(z(m)-z(i))*zn <= 0);
if (border)
ii(m)=[i];
jj(m)=[j];
kk(m)=[k];
end
end
end
end
end
end
end
wart=[ii' jj' kk']
dd
figure(2)
triplot(wart,x,y)
This is what I should get from this script. This matrix is generated as delaunay() matlab function:
dd =
6 7 2
7 1 2
4 6 2
1 3 2
4 3 5
6 4 5
2 3 4
This is what I get from implementation :
wart =
4 7 6
4 7 5
4 7 5
4 7 5
4 7 5
4 6 5
4 6 5
Could anyone of you tell me what is wrong with this ? Where is a mistake or simply guide me?
jils.
The issue is in your innermost loop, here:
if (zn < 0)
border=zn;
for m=1:length(x)
border = (border) & ...
((x(m)-x(i))*xn +...
(y(m)-y(i))*yn +...
(z(m)-z(i))*zn <= 0);
if (border)
ii(m)=[i];
jj(m)=[j];
kk(m)=[k];
end
end
end
You want to check if the triangle defined by points [i,j,k] is valid. Only if it is so for all m (no points inside the circumcircle) do you want to save those three points into your output. Currently, if the first point you check is outside the circumcircle, those three points get saved no matter what. In addition, since you loop over the same m for each possible triangle, even if you find the correct values you're likely overwriting them later on. This is also why you get repeats of the same values in your output.
In these cases it is always worth stepping through (mentally, manually on the command line, or using debug methods) your loops to see what happens. Your first output 4 7 6 doesn't appear in the inbuilt function results. So set your i,j,k to those values and see what happens in that inner loop.
Incidentally, you don't actually need a loop there. Check all values at once by doing something like:
border = (x-x(i)).*xn + (y-y(i)).*yn + (z-z(i)).*zn;
if all(border<0)
% then store coordinates
end
You can start with an empty output ([]) and append (using end+1), or calculate the max number of triangles and preallocate your output to that size, use a counter variable to keep track of how many you find and put them in the right place in the output array, and then trim the output to size right at the end. If you're planning to have larger input data sets, it would be better to preallocate.
suppose that we are determine peaks in vector as follow:
we have real values one dimensional vector with length m,or
x(1),x(2),.....x(m)
if x(1)>x(2) then clearly for first point peak(1)=x(1);else we are then comparing x(3) to x(2),if x(3)
[ indexes,peaks]=function(x,m);
c=[];
b=[];
if x(1)>x(2)
peaks(1)=x(1);
else
for i=2:m-1
if x(i+1)< x(i) & x(i)>x(i-1)
peak(i)=x(i);
end;
end
end
end
peaks are determined also using following picture:
sorry for the second picture,maybe it is not triangle,just A and C are on straight line,but here peak is B,so i can't continue my code for writing algorithm to find peak values in my vector.please help me to continue it
updated.numercial example given
x=[2 1 3 5 4 7 6 8 9]
here because first point is more then second,so it means that peak(1)=2,then we are comparing 1 to 3,because 3 is more then 1,we now want to compare 5 to 3,it is also more,compare 5 to 4,because 5 is more then 4,then it means that peak(2)=5,,so if we continue next peak is 7,and final peak would be 9
in case of first element is less then second,then we are comparing second element to third one,if second is more then third and first elements at the same time,then peak is second,and so on
You could try something like this:
function [peaks,peak_indices] = find_peaks(row_vector)
A = [min(row_vector)-1 row_vector min(row_vector)-1];
j = 1;
for i=1:length(A)-2
temp=A(i:i+2);
if(max(temp)==temp(2))
peaks(j) = row_vector(i);
peak_indices(j) = i;
j = j+1;
end
end
end
Save it as find_peaks.m
Now, you can use it as:
>> A = [2 1 3 5 4 7 6 8 9];
>> [peaks, peak_indices] = find_peaks(A)
peaks =
2 5 7 9
peak_indices =
1 4 6 9
This would however give you "plateaus" as well (adjacent and equal "peaks").
You can use diff to do the comparison and add two points in the beginning and end to cover the border cases:
B=[1 diff(A) -1];
peak_indices = find(B(1:end-1)>=0 & B(2:end)<=0);
peaks = A(peak_indices);
It returns
peak_indices =
1 4 6 9
peaks =
2 5 7 9
for your example.
findpeaks does it if you have a recent matlab version, but it's also a bit slow.
This proposed solution would be quite slow due to the for loop, and you also have a risk of rounding error due to the fact that you compare the maximal value to the central one instead of comparing the position of the maximum, which is better for your purpose.
You can stack the data so as to have three columns : the first one for the preceeding value, the second is the data and the third one is the next value, do a max, and your local maxima are the points for which the position of the max along columns is 2.
I've coded this as a subroutine of my own peak detection function, that adds a further level of iterative peak detection
http://www.mathworks.com/matlabcentral/fileexchange/42927-find-peaks-using-scale-space-approach
If I write a random matrix (A) and get results:
ans = 1 2 3 4 %next row 5 6 7 8
how can I get it written in this form:
A = [1,2,3,4;5,6,7,8]; ?
(Of course I want to avoid retyping or copy-pasting it)
If I understand your question correctly, mat2str is what you are looking for. Although it won't use commas, but spaces, and overwrite ans (i.e. ans will be of type char afterwards).
Example (the second argument limits the number of digits):
>> rand(2,3); mat2str(ans,2)
ans =
[0.42 0.79 0.66;0.92 0.96 0.036]
The last answer that you calculated is saved in a special variable named ans. Simply assign that value to A.
% some calculations
[1,2,3,4;5,6,7,8]
% assign to A
A = ans;