how to store the values into a single variable - matlab

I have created a X-by-Y matrix . Multiplies each element of the matrix with the X(length) and Y(breadth) which generates a rectangular matrix(This is done in order to plot the points throughout the length and breadth of the matrix).
But I am not able to store all the values generated from the for loop into y and x.
1) Kindly please tell me how to store the values into a single variable in the below program
2) And I am not able to plot two unequal dimensions which are generated after the operations are performed in the below program.
X=input('enter the dimension of the matrix:');
Y=input('enter the dimension of the matrix:');
a=rand(X,Y)
for i=1:X
x=a(i,:)
px=x.*X
end
for j=1:Y
y=a(:,j)
py=y.*Y
end

Each iteration of your "for" loops overwrites x, px, y, and py with new values, so it drops all of the old values. To be honest, I wouldn't even bother with the for loops. Assuming that what you really need is px and py, I would just do this-
px = a * X;
py = a * Y;

There are a number of MATLAB functions that could be used to get a matrix with random values.
randi(maxi, X, Y) looks like the one more useful here.
Get ride of the for loops:
X=input('enter the dimension of the matrix:');
Y=input('enter the dimension of the matrix:');
maxi = 100;
a=randi(maxi,X,Y);
and if you want to visualize it do:
imagesc(a);

Related

knnsearch from Matlab to Julia

I am trying to run a nearest neighbour search in Julia using NearestNeighbors.jl package. The corresponding Matlab code is
X = rand(10);
Y = rand(100);
Z = zeros(size(Y));
Z = knnsearch(X, Y);
This generates Z, a vector of length 100, where the i-th element is the index of X whose element is nearest to the i-th element in Y, for all i=1:100.
Could really use some help converting the last line of the Matlab code above to Julia!
Use:
X = rand(1, 10)
Y = rand(1, 100)
nn(KDTree(X), Y)[1]
The storing the intermediate KDTree object would be useful if you wanted to reuse it in the future (as it will improve the efficiency of queries).
Now what is the crucial point of my example. The NearestNeighbors.jl accepst the following input data:
It can either be:
a matrix of size nd × np with the points to insert in the tree where nd is the dimensionality of the points and np is the number of points
a vector of vectors with fixed dimensionality, nd, which must be part of the type.
I have used the first approach. The point is that observations must be in columns (not in rows as in your original code). Remember that in Julia vectors are columnar, so rand(10) is considered to be 1 observation that has 10 dimensions by NearestNeighbors.jl, while rand(1, 10) is considered to be 10 observations with 1 dimension each.
However, for your original data since you want a nearest neighbor only and it is single-dimensional and is small it is enough to write (here I assume X and Y are original data you have stored in vectors):
[argmin(abs(v - y) for v in X) for y in Y]
without using any extra packages.
The NearestNeighbors.jl is very efficient for working with high-dimensional data that has very many elements.

MATLAB - How to plot a function using an array with negative indices?

I'm trying to figure out this bootleg programming language but keep getting stumped on things like this.
My code is as follows:
clc;
clear;
for i = -3:6;
x(i) = i;
y(i) = (i^4)-(4*(i^3))-(6*(i^2))+15; %being my given function
end
plot(x,y)
It works if I start from 1 because it's a positive integer. It can't access zero nor negative values. How do I go around this?
edit: thanks for the swift response you guys, I like your methods and definitely wanted to approach it different ways but one of the requirements in my text is to use the for loop, sadly
Since you can't access array elements with negative indices, you'll need to use a different variable than i to keep track of each element in x and y; this new variable should start at 1 and increment with every loop iteration.
But you don't even need to worry about managing that; you can simply assign -3:6 to x and compute your function using x as an array:
clc;
clear;
x = -3:6;
y = (x.^4)-(4*(x.^3))-(6*(x.^2))+15;
plot(x,y)
However, this will produce a graph that looks a bit jagged. If you want x to contain more points, you can use linspace() instead:
clc;
clear;
x = linspace(-3, 6); % (similar to -3:0.09:6)
y = (x.^4)-(4*(x.^3))-(6*(x.^2))+15;
plot(x,y)
You can do this even without a for loop.
x = -3:6;
y = (x.^4)-(4*(x.^3))-(6*(x.^2))+15;
Matlab is way more effective if it's used without loops. For your case with this small range it will have no effect but if you go for way more elements you increase the speed of your code using this approach.
To answer you original question. The problem is that you are using the index based vector access. And the first element in Matlab vector is defined with index 1.
For your edit and the requirement of using the for loop you can use this approach
x = -3:6;
y = zeros(1, length(x));
% initialization prevents the vector size being changed in every iteration
for i = 1:length(x)
y = (x(i)^4)-(4*(x(i)^3))-(6*(x(i)^2))+15;
end

How do I write correlation coefficient manually in matlab?

The following is a function that takes two equal sized vectors X and Y, and is supposed to return a vector containing single correlation coefficients for image correspondence. The function is supposed to work similarly to the built in corr(X,Y) function in matlab if given two equal sized vectors. Right now my code is producing a vector containing multiple two-number vectors instead of a vector containing single numbers. How do I fix this?
function result = myCorr(X, Y)
meanX = mean(X);
meanY = mean(Y);
stdX = std(X);
stdY = std(Y);
for i = 1:1:length(X),
X(i) = (X(i) - meanX)/stdX;
Y(i) = (Y(i) - meanY)/stdY;
mult = X(i) * Y(i);
end
result = sum(mult)/(length(X)-1);
end
Edit: To clarify I want myCorr(X,Y) above to produce the same output at matlab's corr(X,Y) when given equal sized vectors of image intensity values.
Edit 2: Now the format of the output vector is correct, however the values are off by a lot.
I recommend you use r=corrcoef(X,Y) it will give you a normalized r value you are looking for in a 2x2 matrix and you can just return the r(2,1) entry as your answer. Doing this is equivalent to
r=(X-mean(X))*(Y-mean(Y))'/(sqrt(sum((X-mean(X)).^2))*sqrt(sum((Y-mean(Y)).^2)))
However, if you really want to do what you mentioned in the question you can also do
r=(X)*(Y)'/(sqrt(sum((X-mean(X)).^2))*sqrt(sum((Y-mean(Y)).^2)))

storing and accessing with matrices of more than two dimensions

I am using ode45 to solve a system with 4 variables. For each time I execute the code:
[t y] = ode45(#func, tspan, y0);
t will be a one dimensional matrix, while y will be a 2 dimensional matrix, with 4 columns, each of which is the solution for one of the variables in question.
I want to run multiple trials of this, and keep them in a 3D matrix my_y_results and my_t_results. I want to be able to, for example, plot the final value of a certain variable for a particular initial condition, as I change the initial condition. How would I do this?
So, on each iteration of the loop below, I want to place the new values in a new matrix.
for i = 1:1:10
y0 = **some value**
[t_temp, y_temp] = ode45(#func, tspan, y0);
my_t_results = **something**
my_y_results = *something* //your code here
end
Also, how would I access the different values after setting them? For example, to get the last value of the variable y(1) for each of the 10 trials, what code would I use?
Higher dimensions can be accessed similar to the usual row and column dimensions. Let's assume t is Nx1 and y is Nx4, and that we are running M trials (note that each trial will have to have the same number of points, N, in order to store the data in a 3-dimensional array).
Your array my_t_results doesn't have to be 3-dimensional and can simply be NxM, where each column is the time vector for a different trial.
The array my_y_results would be Nx4xM and can be defined in MATLAB with:
my_y_results = zeros(N,4,M);
At the end of each i'th trial you would store the results like this:
my_y_results(:,:,i) = y;
And of course accessing the data is similar:
y_i = my_y_results(:,:,i);

How do I create a simliarity matrix in MATLAB?

I am working towards comparing multiple images. I have these image data as column vectors of a matrix called "images." I want to assess the similarity of images by first computing their Eucledian distance. I then want to create a matrix over which I can execute multiple random walks. Right now, my code is as follows:
% clear
% clc
% close all
%
% load tea.mat;
images = Input.X;
M = zeros(size(images, 2), size (images, 2));
for i = 1:size(images, 2)
for j = 1:size(images, 2)
normImageTemp = sqrt((sum((images(:, i) - images(:, j))./256).^2));
%Need to accurately select the value of gamma_i
gamma_i = 1/10;
M(i, j) = exp(-gamma_i.*normImageTemp);
end
end
My matrix M however, ends up having a value of 1 along its main diagonal and zeros elsewhere. I'm expecting "large" values for the first few elements of each row and "small" values for elements with column index > 4. Could someone please explain what is wrong? Any advice is appreciated.
Since you're trying to compute a Euclidean distance, it looks like you have an error in where your parentheses are placed when you compute normImageTemp. You have this:
normImageTemp = sqrt((sum((...)./256).^2));
%# ^--- Note that this parenthesis...
But you actually want to do this:
normImageTemp = sqrt(sum(((...)./256).^2));
%# ^--- ...should be here
In other words, you need to perform the element-wise squaring, then the summation, then the square root. What you are doing now is summing elements first, then squaring and taking the square root of the summation, which essentially cancel each other out (or are actually the equivalent of just taking the absolute value).
Incidentally, you can actually use the function NORM to perform this operation for you, like so:
normImageTemp = norm((images(:, i) - images(:, j))./256);
The results you're getting seem reasonable. Recall the behavior of the exp(-x). When x is zero, exp(-x) is 1. When x is large exp(-x) is zero.
Perhaps if you make M(i,j) = normImageTemp; you'd see what you expect to see.
Consider this solution:
I = Input.X;
D = squareform( pdist(I') ); %'# euclidean distance between columns of I
M = exp(-(1/10) * D); %# similarity matrix between columns of I
PDIST and SQUAREFORM are functions from the Statistics Toolbox.
Otherwise consider this equivalent vectorized code (using only built-in functions):
%# we know that: ||u-v||^2 = ||u||^2 + ||v||^2 - 2*u.v
X = sum(I.^2,1);
D = real( sqrt(bsxfun(#plus,X,X')-2*(I'*I)) );
M = exp(-(1/10) * D);
As was explained in the other answers, D is the distance matrix, while exp(-D) is the similarity matrix (which is why you get ones on the diagonal)
there is an already implemented function pdist, if you have a matrix A, you can directly do
Sim= squareform(pdist(A))