A = 100 x 3 matrix
B = 200 x 10 x 100 matrix
column 2 of A contains index to dimension 1 of B.
column 3 of A contains 2 possible values: 0 or 1.
Based on the following conditions, I want to extract the values in B.
x = find(A(:, 3) == 0);
y = find(A(:, 3) == 1);
The index to dimension 1 of B is:
x_idx = A(x, 2);
y_idx = A(y, 2);
How can I get a 2-d matrix, such that:
C = B(x_idx, :, x);
D = B(y_idx, :, y);
See if this works for you -
ind1 = sub2ind(size(B), x_idx, ones(numel(x),1), x)
C = B(bsxfun(#plus,ind1,size(B,1)*[0:size(B,2)-1])') %%//'
ind2 = sub2ind(size(B), y_idx, ones(numel(y),1), y)
D = B(bsxfun(#plus,ind2,size(B,1)*[0:size(B,2)-1])')
Related
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!
Suppose I have the n x m matrices A,B,C. I want to make a "3 x 1" block-matrix Y, such that
Y(1,1) = A, Y(2,1) = B, Y(3,1) = C. Is that possible in MATLAB?
As an alternative to storing the three n x m matrices in a cell vector, consider storing them in a three-dimensional array of size n x m x 3. You can use the cat command to concatenate the matrices along the third dimension, for example:
>> n = 2; m = 3;
>> A = rand(n, m); B = rand(n, m); C = rand(n, m);
>> Y = cat(3, A, B, C)
Y(:,:,1) =
0.792207329559554 0.655740699156587 0.849129305868777
0.959492426392903 0.0357116785741896 0.933993247757551
Y(:,:,2) =
0.678735154857773 0.743132468124916 0.655477890177557
0.757740130578333 0.392227019534168 0.171186687811562
Y(:,:,3) =
0.706046088019609 0.27692298496089 0.0971317812358475
0.0318328463774207 0.0461713906311539 0.823457828327293
This can also be accomplished by indexing, for example:
>> Y(:,:,1) = A; Y(:,:,2) = B; Y(:,:,3) = C;
>> Y
Y(:,:,1) =
0.792207329559554 0.655740699156587 0.849129305868777
0.959492426392903 0.0357116785741896 0.933993247757551
Y(:,:,2) =
0.678735154857773 0.743132468124916 0.655477890177557
0.757740130578333 0.392227019534168 0.171186687811562
Y(:,:,3) =
0.706046088019609 0.27692298496089 0.0971317812358475
0.0318328463774207 0.0461713906311539 0.823457828327293
Yes, this is available using cell arrays.
if you have as stated three matrices A,B,C of size n x m.
to assign them to Y your code should be.
Y{1,1} = A;
Y{2,1} = B;
Y{3,1} = C;
As you see cell arrays use {} instead of ().
For more information about cell arrays visit Matlab help
I have matrix C (m x n)
I need to find the indices of the minimum element within specific columns (m+1 to n-1).
d = min(c(c>0));
[x,en] = find(c == d);
please help
You can use min() for that:
g = c(:,m+1:n-1); %get the subset first
[d,ind] = min(g(g>0)); %get the minimum and index of that minimum
This might be what you want,
Cm = C(:,m + 1 : n - 1);
d = min(Cm(Cm>0));
[row,col] = find(Cm == d);
if numel(col) > 0
col = col + m;
end
Given some multidimensional matrix A in Octave / Matlab,
What's the easiest way to get a matrix of the same size as A where all elements are replaced by their index along the k'th dimension
ie for the matrix
A =
ans(:,:,1) =
0.095287 0.191905
0.226278 0.749100
ans(:,:,2) =
0.076826 0.131639
0.862747 0.699016
I want a function f such that
f(A,1) =
ans(:,:,1) =
1 1
2 2
ans(:,:,2) =
1 1
2 2
f(A,2) =
ans(:,:,1) =
1 2
1 2
ans(:,:,2) =
1 2
1 2
and
f(A, 3) =
ans(:,:,1) =
1 1
1 1
ans(:,:,2) =
2 2
2 2
Also, given a sparse matrix B
What's the easiest way to get another sparse matrix of the same size where the nonzero elements are replaced by their index along the k'th dimension? (so same problem as above, but for only the nonzero elements)
Ideally I'm looking for a way which is well-vectorized for octave (meaning it doesn't explicitly loop over anything)
CLARIFICATION: For the sparse matrix one, I'm looking for a solution which does not involve creating a full size(B) matrix at any point
ndgrid() does what you want, although not in the format you are looking for. If you know the dims of the input A beforehand, you can use the following line to create the N-dimentional mesh grid:
% for matrix a where ndims(a) == 3
[x, y, z] = ndgrid (1:size(a,1), 1:size(a,2), 1:size(a,3));
% x is like f(a, 1)
% y is like f(a, 2)
% z is like f(a, 3)
You may be able to write a custom wrapper around ndgrid() to convert it to the function format you are looking for.
In case anyone's curious, since I didn't know about ndgrid, here's the answer I came up with:
function [y] = indices(a,k)
s = size(a);
n = s(k);
D = length(s);
x = permute(a,[k,1:(k-1),(k+1):D]);
y = reshape(x,n,[]);
y = diag(1:n) * ones(size(y));
y = reshape(y,size(x));
y = permute(y,[(2:k),1,(k+1):D]);
endfunction
function [y] = spindices(a,k)
s = size(a);
n = s(k);
D = length(s);
x = permute(a,[k,1:(k-1),(k+1):D]);
y = reshape(x,n,[]);
y = spdiag(1:n) * spones(y);
y = reshape(y,size(x));
y = permute(y,[(2:k),1,(k+1):D]);
endfunction
I have a 1xm cell array A{}, with each element of the array being NxN matrix and a matrix W(N1,m).
I need to calculate
Sum(j) = W(j,1)*A{1,1} + W(j,2)*A{1,2}
and I am doing the following:
for j=1:N1
sum=false(N);
for k=1:m
sum = sum + W(j,k)*A{1,k};
end
Sum(j)=sum
end
Or more visually :
Matrix W(let's say N1=2)
|W11 W12||A{1,1}| = |W11*A{1,1} + W12*A{1,2}|
|W21 W22||A{1,2}| = |W21*A{1,1} + W22*A{1,2}|
Is there a way of doing it without using the loops?
To do that without for-loops, you can rape (pardon the expression) the arrayfun command:
w_func = #(j)arrayfun(#(k)(W(j, k) * A{k}), 1:m, 'Un', 0)
sum_func = #(x)sum(cat(3, x{:}), 3)
S = arrayfun(#(j)sum_func(w_func(j)), 1:N1, 'Un', 0);
This produces a cell array S that contains all the sums, from S{1} to S{N1}.
I'm confused over what you are trying to do, but if I understand it correctly, this code should work:
temp = cell2mat(A);
a_sum = temp*repmat(eye(n),m,1); % this reduces A by performing sum like operation so [1 1 1 3;0 1 0 2]
% becomes [2 4; 0 3]
Sum = W * a_sum
I am also not sure I understood the question, but here is some code to consider:
%# create some data resembling what you described
N = 2;
m = 4;
N1 = 5;
W = rand(N1,m);
A = cell(1,m); for i=1:m, A{i} = rand(N); end
%# do the multiplications
s = cell(N1,1);
for j=1:N1
AA = cellfun(#times, A, num2cell(W(j,:)), 'UniformOutput',false);
s{j} = sum(cat(3,AA{:}), 3);
end
The cell array s now contains the result such that:
s{j} = W(j,1)*A{1} + W(j,2)*A{2} + ... + W(j,m)*A{m}
thus s is a cell array of size N1-by-1, where each cell contains an N-by-N matrix