MATLAB - vectorize iteration over two matrices used in function - matlab

I have two matrices X and Y, both of order mxn. I want to create a new matrix Z of order mx1 such that each i th entry in this new matrix is computed by applying a function to ith and ith row of X and Y respectively. In my case m = 100000 and n = 2. I tried using a loop but it takes forever.
for i = 1:m
Z = function(X(1,:),Y(1,:), constant_parameters)
end
Is there an efficient way to vectorize it?
EDIT 1
This is the function
function [peso] = fxPesoTexturaCN(a,b, img, r, L)
ac = num2cell(a);
bc = num2cell(b);
imgint1 = img(sub2ind(size(img),ac{:}));
imgint2 = img(sub2ind(size(img),bc{:}));
peso = (sum((a - b) .^ 2) + (r/L) * (imgint2 - imgint1)) / (2*r^2);
Where img, r, L are constats. a is X(1,:) and b is Y(1,:)
And the call of this function is
peso = bsxfun(#(a,b) fxPesoTexturaCN(a,b,img,r,L), a, b);

Related

There is a function in Matlab to create a matrix, where each element is the same function of matrix indexes?

For example, a matrix where each value at row r and column c is
a=[r^2+c^2]
like a=[1, 4; 4; 18]
or
A=[F(r,c)]
A=[F(1,1) F(1,2) F(1,3);
F(2,1) F(2,2) F(2,3);
F(3,1) F(3,2) F(3,3)]
or
A(r,c)=F(r,c)
Mehtod 1
You can do it manually. First, create two matrices for rows and columns indices (suppose the matrix is n x m):
R = repmat((1:n).',[1, m]);
C = repmat((1:m),[n, 1]);
Then, write the function base on these two:
result = R.^2 + C.^2; % F(x,y) = x^2 + y^2
Or define the function inline and apply it on those two:
F = #(x,y)(x.^2 + y.^2);
result = F(R,C);
Mehtod 2
By #Cris Luengo, you can do it the first part by the meshgird function as well. Hence, we can generate R and C like the following:
[C,R] = meshgrid(1:n, 1:m)

Matlab equivalent code of the following equation

I have an equation for which I am trying to write a code in Matlab, but I am not sure if my code is right. The equation is as follows:
Where I think the iteration is over the superscript i.e. k, k+1 etc and the dimensions are marked by subscripts m, n, n'. The notations are not well defined in the literature so I think this is how it should be.
My code segment for this equation is as follows:
c_n = [1,2,3,4]'; % c^(0)_n (nx1) vector
K = 50;
d = [0.5,0.9]';
for k = 1:1:K
c_n = c_n.*((sum(A_mn'*d/(sum(A_mn*c_n,2)),2))./sum(A_mn',2)) ;
end
Is this code correct for the above equation?. The summations in the equation are confusing me.
If A is a matrix with m rows and n columns, then the sum is just the sum of the nth row in AT. This is the same as the corresponding sum of the nth column in A: . The matrix multiplication it represents works out nicer with the transpose because matrix multiplications are just sums of weighted rows.
Similarly, is the mth row of A, weighted element-wise by by c.
We can assume that c and d are column vectors of size n and m, respectively. (d' will be represented by just plain d in the code). In that case, most of the operations can be reduced to matrix operations:
is just the matrix product A * c, which yields a column vector of size m.
then becomes the element-wise ratio d ./ (A * c), also of size m.
The ratio is used to scale the elements of the sum of AT in the numerator, making it the matrix product A.' * (d ./ (A * c)) of size n.
Each element of that is scaled by , which can be represented by either A.' * ones(m, 1) or sum(A, 1).', so the final matrix product is just c .* (A.' * (d ./ (A * c)) ./ sum(A, 1).').
You can pre-calculate sum(A, 1).', call it e to get the following:
c = [1; 2; 3; 4];
d = [0.5; 0.9];
A = ... some 2x4 matrix;
e = sum(A, 1).';
k = 50;
for i = 1 : k
c = c .* (A.' * (d ./ (A * c)) ./ e);
end
If you want to retain the intermediate values of c for each k, you can allocate a matrix of size n, k + 1 and fill that in with each column representing a new iteration of c:
c = zeros(4, 51);
c(:, 1) = [1; 2; 3; 4];
for i = 1 : k
c(:, k + 1) = c(:, k) .* (A.' * (d ./ (A * c(:, k))) ./ e);
end

How to apply a function over a matrix and simultaneously pass parameters?

I have a matrix e.g. as follows:
N = magic(100);
I want to apply a function on each column and save its output in another matrix.
Here is my function
function z = nikfoo(y, lambda, p)
m = length(y);
D = diff(speye(m), 2);
w = ones(m, 1);
for it = 1:10
W = spdiags(w, 0, m, m);
C = chol(W + lambda * D' * D);
z = C \ (C' \ (w .* y));
w = p * (y > z) + (1 - p) * (y < z);
end
At first I tried to make a matrix the same size as my data
% I take the size of my matrix
[a, b] = size(N);
% make the same size matrix with zeros
corrNiki = zeros(a,b);
then I try to do it as follows
% I set the lambda as 1000 and p as 0.1
for i = 1:b
corrNiki(i) = nikfoo(N(i),1000,0.1);
end
So now I have these questions
how can I pass this function with the fixed lammda and p and save the results in corrNiki?
how can I also pass different values to the Lamda in a range and in P in a range and then save their outputs ?
for example
Lammda 1000 and P0.1 is saved in data1
Lammda 2000 and P0.01 is saved in data2
.
.
.

How to find an arbitrary perpendicular vector of another vector in MATLAB?

I need to create arbitrary perpendicular vector n with components (a, b, c) to another known vector k with components (x,y,z).
The following code creates arbitrary vector n, but I need random numbers for components in the range [-inf, inf] how can I acheive that? (because otherwise vector components created may not exceed some value in given case 10^11 ) Or maybe concept "arbitrary vector" does not require that?
function [a,b,c] = randomOrghogonalVector(x,y,z)
a = 0;
b = 0;
c = 0;
randomDistr = rand * 10^11 * 2 - 10^11; % issue 1
% excluding trivial solution
if x == 0 && y == 0 && z ==0
a = NaN; b = a; c = a;
else
if z ~=0
a = randomDistr;
b = randomDistr;
c = - (x * a + b * y ) / z;
else
if z == 0 && x ~= 0
c = randomDistr;
b = randomDistr;
a = - (z * c + b * y ) / x;
else
if z == 0 && x == 0 && y ~= 0
c = randomDistr;
a = randomDistr;
b = - (z * c + a * x ) / y;
end
end
end
end
The easiest solution I see is to first find a random vector that is orthogonal to your original vector, and then give it a random length. In Matlab, this can be done by defining the following function
function [a, b, c] = orthoVector(x, y, z)
xin = [x;y;z];
e = xin;
while ((e'*xin)==xin'*xin)
e = 2.*rand(3,1)-1;
end
xout = cross(xin, e);
xout = 1.0/(rand()) * xout;
a = xout(1);
b = xout(2);
c = xout(3);
end
Line-by-line, here's what I'm doing:
you asked for this format [a,b,c] = f(x,y,z). I would recommend using function xout = orthoVector(xin), which would make this code even shorter.
Since Matlab handles vectors best as vectors, I'm creating vector xin.
e will be one random vector, different from xin used to compute the orthogonal vector. Since we're dealing with random vectors, we initialize it to be equal to xin.
For this algorithm to work, we need to make sure that e and xin are pointing in different directions. Until this is the case...
...create a new random vector e. Note that rand will give values between 0 and 1. Thus, each component of e will be between -1 and 1.
Ok, if we end, e and xin are pointing in different directions
Our vector xout will be orthogonal to xin and e.
Let's multiply vector xout by a random number between 1 and "very large"
a is first component of xout
b is second component of xout
c is third component of xout
all done.
Optional: if you want to have very large vectors, you could replace line 8 by
xout = exp(1./rand())/(rand()) * xout;
This will give you a very large spread of values.
Hope this helps, cheers!

How to deal with recursive loop in MATLAB?

I am trying to compute x1^i * x2^j * x3^k * ......
This is my code so far:
for l = 1:N
f = 1;
for i = 0:2
for j = 0:2-i
for k = 0:2-j
for m = 0:2-k
g(l,f) = x1(l)^i*x2(l)^j*x3(l)^k*x4(l)^m;
f = f+1;
end
end
end
end
end
How can I do this easier or without a loop?
I do not have MATLAB on hand here, but what I'd do is make a vector X = [x1, x2, ..., xn] of bases and a vector P = [i, j, k, ..., z] of powers, and then compute prod(power(X, P)).
power() does an element-wise power function, and prod takes the product of every element in the vector.