Hi everybody I have a simple matrix like this Ex = [ 1 5; 2 5; 4 15; 5 15; 7 25; 8 25]; and it is graph is like below. I want to keep the same shape of the signal with more samples. In other words I need to have more rows in my matrix with corresponding values in between, keeping the same behaviour. Thanks for help. ,
The term you want to look into is interpolation, in this case linear interpolation would do nicely. There's a good blog post on this topic here.
The gist is that you can do what you are after using the interp1 function, like so:
Ex = [ 1 5; 2 5; 4 15; 5 15; 7 25; 8 25];
x_points = [1:0.5:8];
y_points = interp1(Ex(:,1),Ex(:,2),x_points,'linear');
Ex2 = [x_points' y_points'];
This should generate y_points for each of the specified x_points and then combine them into a matrix similar to the input (but with more rows).
Related
I am looking to implement the following equation in MATLAB since I have a very large matrix,
How would I be able to do this? It is not really about the 261 and for the sake of simplicity, we can assume d = 0.94, and there is no need to worry about the squared term nor mean term as I will be able to figure that out if I can get the loop concept down. So for instance, I will just try to calculate an average of all the past values in the rows with specific weights attached to them.
To clarify, we can essentially think of i as indexing the rows of a matrix and so this consists of an entire column which I provided as an example below. Ignoring the infinity, we can just sum it to period t, but the idea is that there is a certain weight placed on all the previous values of the rows where the most recent row has the greatest weight.
I was thinking of using something like this:
R = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10];
d = 0.94;
r = zeros(10,1);
for t = 2:10
r(t,1) = R(t,1);
for i = 1:10
W(i,1) = (1-d)*(d.^i)*r(t,1);
end
end
Or even indexing t = 1:10.
None of these works. In essence, I want to be able to calculate a mean for which there is greater weight placed to the most recent value. So for example, at row t=4, the value I would get would be:
(1-0.94)(0.94^3)*(1) + (1-0.94)(0.94^2)(2) +(1-0.94)(0.94)(3).
Right, if I understand you correctly, I think the following should work:
R = [1 2 3 4 5 6 7 8 9 10];
d = 0.94;
W = zeros(size(R));
% at t = 1, sigma will be 0
for t = 2:length(R)
meanR = mean(R(1:t-1));
for i = 1:t-1
W(t) = W(t) + 261*(1-d)*(d.^(t-i))*(R(i) - meanR)^2;
end
end
I have a data set as follows:
Data = [4 12; 5 10; 8 7; 5 3; 5 4; 2 11; 5 4; 3 8; 6 2; 7 4; 10 8; 8 9; 10 9; 10 12]
Then I proceed with:
[idx,ctrs, sumD] = kmeans(Data,3)
It gives me the centroids and sumD (sums of point-to-centroid distances within cluster) like:
ctrs = [5.6000 3.4000; 3.5000 10.2500; 9.2000 9.0000]
sumD = [6.4000; 13.7500; 18.8000]
Whereas according to Excel Solver (from a published article), ctrs and sumD are as follows for k=3:
ctrs = [5.21815716 3.66736761; 3.615385665 10.461533; 9.47841197 8.75055345]
sumD = [5.151897802; 7.285383286; 8.573829765]
(NB: In that article, the authors give an initial (seed) centroid to each cluster such as [4 4; 5 12; 10 6] by visual decision from the plot.)
Apparently, Excel finds more accurate ctrs values thereby smaller sumD values. I could not achieve this with Matlab. That's why I used other parameters of kmeans function. I used 'replicates'` and 'options' (MaxIter) and also 'start' parameters - even with 3D array seed - to no avail. I even adopted the same initial seed from the article to Matlab. Followings are what I tried and failed:
First:
opts = statset('MaxIter',100);
Seed = [4 4; 5 12; 10 6];
[idx,ctrs] = kmeans(Data,3,'Replicates',50,'options',opts,'start',Seed)
This gives an error: The third dimension of the 'Start' array must match the 'replicates' parameter value.
Second:
I created a 3D array of 50 pages where the first page is the same initial seed above and the rest 49 are random. I created the random pages as:
T = rand(3,2,49);
After that, I created the 50 pages 3D array like this:
Seed2 = cat(3,Seed,T);
Then used kmeans:
[idx,ctrs] = kmeans(Data,3,'Replicates',50,'options',opts,'start',Seed2)
However, Matlab gave warnings indicated that all the replicates after the first replication were terminated due to empty cluster created at iteration 1. Also, the idx, ctrs and sumD values obtained were still the same as before - as if I ran my very first function above (i.e. [idx,ctrs, sumD] = kmeans(Data,3) ).
I am stuck. I am trying to verify the results of the Excel solver published in the article using Matlab because then I will apply the same algorithm applied on 14 observations from the article to a larger data set of 900+ observations.
What am I doing wrong? What should I correct in my coding to obtain the same or much similar result of the Excel Solver?
The difference appears to be in the choice of the measure of distance used, not in the coding. There is more than one way to define "distance" in this context.
MATLAB uses squared Euclidean distance by default. By hand calculating this with the MATLAB results I can replicate the sumD results you get. However, using squared Euclidean distance measure with the results you give from the paper gives a higher value of sumD.
I get the same results for sumD as the paper if I use plain (not squared) Euclidean distance. Using this measure the MATLAB results return higher values for sumD.
So neither result is wrong as such, they're just measuring "rightness" in different ways.
How can you be certain that excel values are correct and MATLAB kmeans gives you not so accurate result.
With the quick MATLAB script below, I plotted the centroids, and at least visually it seems correct
Data = [4 12; 5 10; 8 7; 5 3; 5 4; 2 11; 5 4; 3 8; 6 2; 7 4; 10 8; 8 9; 10 9; 10 12];
plot(Data(:,1), Data(:,2),'ob','markersize', 10);
axis([min(Data(:,1))-2, max(Data(:,1))+2, min(Data(:,2))-2, max(Data(:,2))+2]);
hold on;
[idx,ctrs, sumD] = kmeans(Data,3);
plot(ctrs(:,1), ctrs(:,2), '*r', 'markersize', 10);
If this is not accurate enough, Instead of trying to customize MATLAB's kmeans, we can define our kmean function. I had implemented the kmeans sometime ago and it seemed easier that asking matlab to fine tune the parameters.
Sorry for the perhaps confusing title...
Basically I have a 3x3 matrix containing elevation angle, azimuth angle and range. I want to generate new matrices each time elevation >5 deg. There are usually about 5 segments that have this data and I want to separate each one into a new matrix.
I know how to index but not sure how to put this condition in...
Thanks
sat_tcs=llh2tcsT(sat_llh,station_llh);
sat_elev=atan2(sat_tcs(3,:),sqrt(sat_tcs(1,:).^2+sat_tcs(2,:).^2));
sat_azim=atan2(-sat_tcs(2,:),sat_tcs(1,:));
range=sqrt(sat_tcs(1,:).^2+sat_tcs(2,:).^2+sat_tcs(3,:).^2);` sat_elev(sat_elev < 5*deg2rad) = NaN; sat_look_tcs=[sat_elev;sat_azim;range];
It would be helpful to have some examples of the input and expected output, but taking a guess at what you mean I'd try this:
elevation_column = 3;
threshold = 5;
m = [1 2 3; 4 5 6; 7 8 9; 1 2 3];
n = m(m(:,elevation_column)>threshold,:);
This produces:
n =
4 5 6
7 8 9
Sorry, I would post an image of my graph but supposedly I need reputation points for that..but it the elevation data looks almost sinusoidal and so it has regions over 5 deg and then falls again. I want to generate a new matrix for every set above this angle
I'm a total beginner to matlab and I'm currently writing a script for extracting data from a thermographic video.
Firstly the video is cut in separate frames. The first frame is opened as a sample picture to define the coordinates of sampling points. The goal is then to select the rgb values of those defined coordinates from a set of frames and save them into a matrix.
Now I have a problem separating the matrix to n smaller matrices.
e.g I'm defining the number of points to be selected to n=2 , with a picture count of 31. Now it returns a matrix stating the rgb codes for 31 pictures, each at 2 points, in a 62x3 double matrix...
Now I want to extract the 1st, 3rd, 5th....etc... row to a new matrix...this should be done in a loop, according to the number of n points...e.g 5 points on each picture equals 5 matrices, containing values of 31 pictures....
this is an extract of my code to analyse the pictures, it returns the matrix 'values'
files = dir('*.jpg');
num_files = numel(files);
images = cell(1, num_files);
cal=imread(files(1).name);
n = input('number of selection points?: ');
imshow(cal);
[x,y] = ginput(n);
eval(get(1,'CloseRequestFcn'))
%# x = input('x-value?: '); manual x selection
%# y = input('y-value?: '); manual y selection
for k = 1:num_files
images{k} = imread(files(k).name);
end
matrix=cell2mat(images);
count=(0:size(matrix,1):size(matrix,1)*num_files);
for k = 1:num_files
a(k)= mat2cell(impixel(matrix,x+count(k),y));
end
values = cat(1,a{:})
Easy fix
Do you mean that if you have:
n = 2;
k = 2; % for example
matrix = [1 2 3;
4 5 6;
7 8 9;
8 7 6];
you want it to become
b{1} = [1 2 3;
7 8 9];
b{2} = [4 5 6;
8 7 6];
This can be easily done with:
for ii = 1:n
b{ii} = matrix(1:n:end,:);
end
Better fix
Of course it's also possible to just reshape your data matrix and use that instead of the smaller matrices: (continuing with my sample data ^^)
>> d=reshape(matrix',3,2,[]);
>> squeeze(d(:,1,:))
ans =
1 7
2 8
3 9
>> squeeze(d(:,2,:))
ans =
4 8
5 7
6 6
Good practice
Or, my preferred choice: save the data immediately in an easy to access way. Here I think it will be an matrix of size: [num_files x num_points x 3]
If you want all the first points:
rgb_data(:,1,:)
only the red channel of those points:
rgb_data(:,1,1)
and so on.
I think this is possible with this:
rgb_data = zeros(num_files, num_points, 3);
for kk = 1:num_files
rgb_data(kk,:,:) = impixel(images{kk},x+count(k),y);
end
But I don't understand the complete meaning of your code (eg: why matrix=cell2mat(images) ??? and then of course:
count=(0:size(matrix,1):size(matrix,1)*num_files);
is just count=0:num_files;
so I'm not sure what would come out of impixel(matrix,x+count(k),y) and I used images{k} :)
The expression is:
for i=1:n
X(:,i) = [P{i}(:)];
end
where X is a DxN matrix and P is a cell-array.
reshape(cat(3,P{:}),[numel(P{1}) n])
Of course, the above solution is just for fun. I would recommend profiling both solutions and only using this one if it has a significant performance advantage.
Maintenance and readability are also very important factors to consider when writing code.
If you obtained the cell array via mat2cell, you may be wanting to arrange blocks of an image into the columns of an array X. This can be achieved in a single step using the command IM2COL
%# rearrange the large array so that each column of X
%# corresponds to the 4 pixels of each 2-by-2 block
X = im2col(largeArray,[2 2],'distinct');
You might be able to get away with:
P{1} = [ 1 2; 3 4];
P{2} = [ 7 8; 9 10];
P{3} = [ 11 12; 13 14];
X = [P{:}]
X =
1 2 7 8 11 12
3 4 9 10 13 14
Then some sort of reshape() to get to where you want to be.