clc
clear all
z=[1 2 3 4 5];
d=[10 20 30 40 50];
plot(d,z)
z=[z fliplr(z)];
z(5)=[];
d=[d fliplr(d)];
d(5)=[];
figure(2)
plot(d,z)
z=[1 2 3 4 5];
z=[z 6 7 8 9];
figure(3)
plot(d,z)
I'm trying to "flip a graph on itself" or "fold it" , the first figure does this "/" the second one ALSO does "/" but it goes forward and then backwards, the third one does ">" and i need it to do "/\"or "^" whatever you think depicts it better, basically repeat the somewhat transpose of a graph, i need a mirror in front of it, something like doing even extensions in Fourier series i believe?
The problem is more complex than this, but this step is vital to keep doing it, please help me do so :/, i AM using Octave, but for something as basic as this MATLAB and Octave codes should be interchangeable.Thanks in advance
Even extension means f(-x) = f(x): same z-value when the argument d changes sign. The process you describe is not exactly that, since the reflected part is to be added at the end of original plot, to make /\ shape out of / shape. This is how it can be done:
ze = [z z(end-1:-1:1)]
de = [d 2*d(end)-d(end-1:-1:1)]
plot(de, ze)
The z-value are just reflected (repeated from end-1 to 1, in reverse order); the d-values are transformed by the map that sends x to 2*d(end) - x. This is a reflection that keeps d(end) fixed.
In your example, ze is [1 2 3 4 5 4 3 2 1] and
de is [10 20 30 40 50 60 70 80 90].
Related
Sorry for the vague title, but I wasn't sure how to name it properly.
Let's say I have this vector:
v=[2 5 8]';
Also I have the range of numbers as follow:
x=2:4
I want to create a for loop that will multiply the vector by 2, then use this newly created vector and multiply it by 3 and then use that and multiply it by 4. What I essentialy want is a 3 by 3 matrix
When I code something like this:
v=[2 5 8]';
for i= 2:4
k=v*i
end
This doesn't work because
a) Instead of multiplying by the next number in the loop it just adds the elements to itself i.e( in the second iteration I want (12, 30, 48)' and not (6,15,24)'
b) It doesn't store all 3 sets of values in the workspace.
EDIT
for i=1:1:length(x)
c1=fftshift(fft(u0z));
c2=exp(-1j*(p^2*x(i)/(2*lamda))).*c1;
c3=ifft(ifftshift(c2));
u1=exp(1j*lamda*(n(i)^2-1)*x(i)/2).*c3;
u0z=u1
end
Edit 2
for k=1:1:length(x)
c1=fftshift(fft(u0z));
c2=exp(-1j*(p^2*x(k)/(2*lamda))).*c1;
c3=ifft(ifftshift(c2));
u1=exp(1j*lamda*(n(k)^2-1)*x(i)/2).*c3;
u0z=u1;
mat(:,k)=u0z;
end
Using MATLAB's cumprod and implicit expansion (for MATLAB before R2016b, you need bsxfun for that), that's a one-liner:
v * cumprod(x)
% bsxfun(#times, v, cumprod(x))
ans =
4 12 48
10 30 120
16 48 192
Hope that helps!
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
Okay, this is a bit tricky to explain, but I have a long .txt file with data (only one column). It could look like this:
data=[18
32
50
3
19
31
48
2
18
33
51
4]
Now, every fourth value (e.g. 18, 19, 18) represents the same physical quantity, just from different measurements. Now, I want Matlab to take every fourth value and put it into an array X=[18 19 18], and like wise for the other quantities.
My solution so far looks like this:
for i=1:3;
for j=1:4:12;
X(i)=data(j);
end
end
... in this example, because there are three of each quantity (therefore i=1:3), and there are 12 datapoints in total (therefore j=1:4:12, in steps of 4). data is simply the loaded list of datapoints (this works fine, I can test it in command window - e.g. data(2)=32).
My problem, doing this, is, that my array turns out like X=[18 18 18] - i.e. only the last iteration is put into the array
Of course, in the end, I would like to do it for all points; saving the 2nd, 6th, and 10th datapoint into Y and so on. But this is simply having more for-loops I guess.
I hope this question makes sense. I guess it is an easy problem to solve.
Why don't you just do?
>> X = data(1:4:end)
X =
18
19
18
>> Y = data(2:4:end)
Y =
32
31
33
You can reshape the data and then either split it up into different variables or just know that each column is a different variable (I'm now assuming each measurement occurs the same number of times i.e. length(data) is a multiple of 4)
data = reshape(data, 4, []).';
So now if you want
X = data(:,1);
Y = data(:,2);
%// etc...
But also you could just leave it as data all in one variable since calling data(:,1) is hardly more hassle than X.
Now, you should NOT use for-loops for this, but I'm gong to address what's wrong with your loops and how to solve this using loops purely as an explanation of the logic. You have a nested loop:
for i=1:3;
for j=1:4:12;
X(i)=data(j);
end
end
Now what you were hoping was that i and j would each move one iteration forward together. So when i==1 then j==1, when i==2 then j==5 etc but this is not what happens at all. To best understand what's going on I suggest you print out the variables at each iteration:
disp(sprintf('i: \tj:'));
for i=1:3;
for j=1:4:12;
disp(sprintf(' %d\t %d',i,j));
end
end
This prints out
i: j:
1 1
1 5
1 9
2 1
2 5
2 9
3 1
3 5
3 9
What you wanted was
disp(sprintf('i: \tj:'));
for i=1:3;
disp(sprintf(' %d\t %d',i,4*i-3));
end
which outputs:
i: j:
1 1
2 5
3 9
applied to your problem:
%// preallocation!
X = zeros(size(data,1)/4, 1)
for i=1:3
X(i)=data(i*4 - 3);
end
Or alternatively you can keep a separate count of either i or j:
%// preallocation!
X = zeros(size(data,1)/4, 1)
i = 1;
for j=1:4:end;
X(i)=data(j);
i = i+1;
end
Just for completeness your own solution should have read
i = 0;
for j=1:4:12;
i = i+1;
X(i)=data(j);
end
Of course am304's answer is a better way of doing it.
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