In a project that I am doing I need to reach floating indexed elements of a matrix. That is to say for instance I want to reach the (16.25,1) th element of a matrix. That might seem odd at the first glance. However, by (16.25,1), I mean the interpolation between (16,1) and (17,1) with weights of .25 and .75 respectively.
Is there a built-in function for that?
Many thanks,
Safak
You can use interp2:
Z = randi(10,10); % 10 x 10 random matrix with integers from 1 to 10
Z(1:2,1:2)
%ans =
% 2 4
% 7 6
% use interp2 to interpolate at row 1.5, col 2
z = interp2(Z,1.5,2)
% z = 6.5000
You can use 2-D interpolation:
ZI = interp2(Z,XI,YI) assumes that X = 1:n and Y = 1:m, where [m,n] = size(Z)
where Z is your matrix, and XI & YI are your fractional indices.
Related
I am trying to graph a surface with a diagonal matrix, the equation I am trying graph is f = x^TDx, x is a 2 by 1 vector and D is a 2 by 2 matrix.
Here is what have so far, but I keep getting error.
x = linspace(-10,10);
y = linspace(-10,10);
[X,Y] = meshgrid(x,y);
D = [1 0; 0 1];
f = #(x,y) [x,y]*D*[x,y].'; % [x,y] is 1 by 2
contour (X,Y,f(X,Y))
Can someone tell me how to get rid of the error? Thanks
Since x and y have the same length, your diagonal matrix D must be a square matrix of size n x n, with n equal to two times the length of your x or y vectors. The reason why you need to multiply the length by two is because the operation [x,y] concatenates the arrays horizontally thus duplicating one of the dimensions.
In this example D is the Identity matrix. See eye for more information.
x = linspace(-10,10); % x is 1x100
y = linspace(-10,10); % y is 1x100
[X,Y] = meshgrid(x,y); % X is 100x100 and Y is 100x100
D = eye(2*numel(x)); % D is 2*100x2*100 = 200x200
f = #(x,y) [x,y]*D*[x,y].'; % [X,Y] is 100x200 and [X,Y].' is 200x100
contour (X,Y,f(X,Y))
If you want D to be a random diagonal matrix, you can accomplish this combining diag with one of the Random Number Generation functions available, like for example randn.
On the previous example, replace D with the following instruction:
D = diag(randn(1,2*numel(x)));
You can also give the coefficients you choose to the diagonal matrix. To do so, you will need to create the vector of coefficients manually, making sure that it has the adequate length, so that it satisfies the conditions explained at the beginning of this post.
Try now replacing D with the following instructions:
v = 1:2*numel(x); % vector of coefficients: v = [1 2 ... 200]
D = diag(v);
I have my data in 2 vectors.
Then using [n,xout] = hist(x,y) returns vectors n and xout containing the frequency counts and the bin locations.
x are my real data and y the segment where I want to build my histogram.
Than I use bar(xout,n) to plot the histogram. In the end I am fitting this histogram with gaussian fit.
Now I would like to know where my real data (each point of vector x), are located in the histogram?
Can someone help me to figure out them?
[~, result] = min(abs(bsxfun(#minus, y(:), x(:).')));
This gives, for each value in x, the index of the closest element in y. So y(result) is the closest element in y for each x.
Example:
>> x = [0.4 1.6 5.3 4.2 3.1 7.8];
>> y = [0 2 4 6 8];
>> [~, result] = min(abs(bsxfun(#minus, y(:), x(:).')))
result =
1 2 4 3 3 5
>> y(result)
ans =
0 2 6 4 4 8
You want to use histc.
[binCounts, idx] = histc(x, y);
Then to find the bin in which a certain value of x is:
bin = idx(x == 0.4);
Just watch out since histc second input is not the centers like hist, but the end value of each bin. So you might need to change your y vector.
I have a matrix 2NxN.
And I want get some parametrs by this matrix. For example it:
How, I can do it?
You may want to break your 12x6 matrix, into two 6x6 matrix; let's say: Z and Zb (last one for z bar). Odd rows are Z and evens are Zb.
Considering M to be the combined matrices:
Z = M(1:2:end,:)
Zb = M(2:2:end,:)
read about the colon(:) operator and end to see what 1:2:end means.
Hope it helps.
From what I understand here are the first three:
% Random Matrix
% Needs to be defined before the functions since the functions look for
% the m variable
m = rand(12,6);
% Function 1
p = #(i,j) sign(m(i,j)+m(i+1,j)) * max(abs(m(i,j)),abs(m(i+1,j)));
p(2,2)
% Function 2 - Avg of row
pavg = #(i) mean(m(i,:));
pavg(2)
% Function 3
c = #(i,j) abs(m(i,j)+m(i+1,j)) / (abs(m(i,j)) + abs(m(i+1,j)));
c(2,2)
I have a range of data represented in the vector C
and have the data classes represented by the vector R
C = [1.71974522292994
1.91974522292994
2.03821656050955
2.13375796178344
2.16560509554140
2.22929936305733
2.35668789808917
2.38853503184713
2.54777070063694
2.61146496815287
2.70700636942675
2.73885350318471
2.83439490445860
2.96178343949045
3.02547770700637
3.31210191082803]
R = [1.71974522292994
2.03821104580359
2.35667686867724
2.67514269155088
2.99360851442453
3.31207433729818
3.63054016017183]
I need to do a histogram and a curve to overlap Standard Normal
z = histc(C,R); bar(R,z);
but the vector z that represents the frequency is not correct.
z = [2 4 4 4 1 1]'
on excell is so, and represents well the histogram
z = [1 1 4 4 4 1 1]'
you could suggest a solution using these two vectors?
Tnks
That's because Matlab's definition of histc:
n(k) counts the value x(i) if edges(k) <= x(i) < edges(k+1)
whereas Excel probably uses the more standard
edges(k) < x(i) <= edges(k+1)
So essentially you need to move the equal sign from below to above. You can get that either
By the trick of changing signs to both vectors and flipping the second (to keep it sorted):
>> z = histc(-C,-R(end:-1:1))
z =
1
1
4
4
4
1
1
Using the very powerful bsxfun function to directly compute the histogram with the equal sign above:
z = diff(sum(bsxfun(#le, C(:), [-inf R(:).'])));
I found it helpful to use this
z = histc(-C,-R);
the loop that I used for inside includes matrices with vectors of different length. I then filled the matrix with NaN
C and classe = [30x14] created by vectors with different lengths + NaN
[nr,nc] = size(C);
Freq = NaN*ones(nr,nc);
R = NaN*ones(nr,nc);
CC = NaN*ones(nr,nc);
I do not find a way in order to create the correct number of figures with the correct subplot.
In each figure there must be 4 subplot.
for k = 1:4
for j= 1 : nc;
R = classe(:,j);
CC = C(:,j);
FF = Freq(:,j);
R = R(~isnan(B)); % toglie i valori NaN
CC = CC(~isnan(CC));
R = sort(R,'descend');
CC = sort(C,'descend');
the line of Plot
FF = histc(-C,-R); % Calculate the J-th absolute frequencies
figure(k); <===?????
subplot(2,2,k) <=== ????????
bar(B,FF);
reassemble the matrices
if length(B)<nr
R(length(R)+1:nr)=NaN; % riempie la parte di colonna vuota
if length(CC)< nr;
C(length(CC)+1:nr)=NaN;
if length(FF)< nr;
FF(length(FF)+1:nr)=NaN;
end
end
end
classe(:,j)=R(:); % matrice classe
C(:,j)=CC(:) % matrice Elementi;
Freq(:,j)=FF(:); %Matrice Frequenze Assolute
end
the next steps concerns the in plotting of 3 figures. Each figure contains 4 subplot
I would also be able to superimpose on each histogram a standard normal curve ...
a tip?
tnks
I am trying to write code to get the 'N-dimensional product' of vectors. So for example, if I have 2 vectors of length L, x & y, then the '2-dimensional product' is simply the regular vector product, R=x*y', so that each entry of R, R(i,j) is the product of the i'th element of x and the j'th element of y, aka R(i,j)=x(i)*y(j).
The problem is how to elegantly generalize this in matlab for arbitrary dimensions. This is I had 3 vectors, x,y,z, I want the 3 dimensional array, R, such that R(i,j,k)=x(i)*y(j)*z(k).
Same thing for 4 vectors, x1,x2,x3,x4: R(i1,i2,i3,i4)=x1(i1)*x2(i2)*x3(i3)*x4(i4), etc...
Also, I do NOT know the number of dimensions beforehand. The code must be able to handle an arbitrary number of input vectors, and the number of input vectors corresponds to the dimensionality of the final answer.
Is there any easy matlab trick to do this and avoid going through each element of R specifically?
Thanks!
I think by "regular vector product" you mean outer product.
In any case, you can use the ndgrid function. I like this more than using bsxfun as it's a little more straightforward.
% make some vectors
w = 1:10;
x = w+1;
y = x+1;
z = y+1;
vecs = {w,x,y,z};
nvecs = length(vecs);
[grids{1:nvecs}] = ndgrid(vecs{:});
R = grids{1};
for i=2:nvecs
R = R .* grids{i};
end;
% Check results
for i=1:10
for j=1:10
for k=1:10
for l=1:10
V(i,j,k,l) = R(i,j,k,l) == w(i)*x(j)*y(k)*z(l);
end;
end;
end;
end;
all(V(:))
ans = 1
The built-in function bsxfun is a fast utility that should be able to help. It is designed to perform 2 input functions on a per-element basis for two inputs with mismatching dimensions. Singletons dimensions are expanded, and non-singleton dimensions need to match. (It sounds confusing, but once grok'd it useful in many ways.)
As I understand your problem, you can adjust the dimension shape of each vector to define the dimension that it should be defined across. Then use nested bsxfun calls to perform the multiplication.
Example code follows:
%Some inputs, N-by-1 vectors
x = [1; 3; 9];
y = [1; 2; 4];
z = [1; 5];
%The computation you describe, using nested BSXFUN calls
bsxfun(#times, bsxfun(#times, ... %Nested BSX fun calls, 1 per dimension
x, ... % First argument, in dimension 1
permute(y,2:-1:1) ) , ... % Second argument, permuited to dimension 2
permute(z,3:-1:1) ) % Third argument, permuted to dimension 3
%Result
% ans(:,:,1) =
% 1 2 4
% 3 6 12
% 9 18 36
% ans(:,:,2) =
% 5 10 20
% 15 30 60
% 45 90 180
To handle an arbitrary number of dimensions, this can be expanded using a recursive or loop construct. The loop would look something like this:
allInputs = {[1; 3; 9], [1; 2; 4], [1; 5]};
accumulatedResult = allInputs {1};
for ix = 2:length(allInputs)
accumulatedResult = bsxfun(#times, ...
accumulatedResult, ...
permute(allInputs{ix},ix:-1:1));
end