Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
We have for example these matrices:
M = rand(30,45,4);
U = rand(4,4);
In first step I want to multiply each element of the matrix M, which is a 4 element vector, with the U matrix. This will result in in a new M1 matrix whose elements are also 1x4. For example, M1(1,1,:) = M(1,1,:)*U; This in matrix dimensions, for the specific example, corresponds in 1x4 = (1x4)(4x4). The whole M1 matrix has the same dimensions as M.
In second step, the M1 must be multiplied with the M' in the same way and obtain the final F matrix which is a 2D matrix with 1D elements. For example, F(1,1) = M1(1,1,:)*M(1,1,:)';
In other words, each element of the F matrix is where is each of the 1x4 elements of the M matrix.
Attached example:
M = rand(600, 800, 4);
U = rand(4,4);
F = nan(size(M,1),size(M,2));
for i=1:size(M,1)*size(M,2)
[r,c]=ind2sub(size(M),i);
F(i) = squeeze(M(r,c,:))'*U*squeeze(M(r,c,:));
end
Elapsed time is 58.627296 seconds.
#Luis Mendo answer:
tic
Mr = reshape(M, [], size(M,3));
result = reshape(sum(Mr*U.*Mr,2), size(M,1), size(M,2));
toc
Elapsed time is 0.062898 seconds.
Could you please somebody suggest a way without using for loops?
Thank you for you time!
PS: Matlab 2013a 64x, Intel(R) Core(TM) i3 CPU 2.40 GHz, 4GB memory
I'm still not sure I understood correctly, but maybe this is what you want:
Mr = reshape(M, [], size(M,4));
result = reshape(sum(Mr*U.*Mr,2), size(M,1), size(M,2));
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 months ago.
Improve this question
enter image description here
k=15;
for i=1:k:length(aa) % aa = 100
for j=1:k:length(bb) % bb = 200
result(j,i) = function(a, b, c, d)
end
end
I am trying to save the calculated value by extracting k by 15 steps.
If you do it this way, the next value will come out from the 1st row, 1st column, 16th row, 1st column, as shown in the picture above, and the value of 0 will come out in between.
So, I'm trying to write additional code that pulls them out in sequence like the right part of the picture...
for ii = size_aa:-1:1
if result(ii,:) == 0
result(ii,:) = [];
end
end
I tried the method of removing zero elements, but it takes too much time. Is there any other way?
Once you have your result matrix, you can use result(result == 0) = []; to remove zero elements and end up with a vector of non-zero results. Here's an example derived from the code the OP posted (I replaced function(a,b,c,d) with rand() for the sake of the example):
k=15;
for i=1:k:100
for j=1:k:200
result(j,i) = rand();
end
end
result(result == 0) = [];
Alternatively, the solution proposed by Cris Luengo generates a matrix that doesn't contain zero elements to start with; I plugged his idea in my sample code:
k=15;
for i=1:k:100
for j=1:k:200
result((j-1)/k+1, (i-1)/k+1) = rand();
end
end
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
How to create a function that generates all the elements in odd positions (e.g. 1,1 1,3 ) in a say...5-by-8 matrix?
I assume that by "odd" you mean where both the index for row and column are odd. This means your resulting matrix should be 3 by 4. Anyway, your code is below.
function Anew = yourFunc(A)
%Create a test matrix of dimensions 5x8 of random numbers from 1-10
A = randi(10,5,8);
%Set the values of all elements with either index being an even number equal to zero
for r = 1 : size(A,1)
for c = 1 : size(A,2)
if rem(r,2) == 0 || rem(c,2) == 0
A(r,c) = 0;
else
continue
end
end
end
%Delete rows that contain ALL zeros
for r = 1 : (size(A,1)/2) + 1
if A(r,:) == 0
A(r,:) = [];
end
end
%Delete columns that contain ALL zeros
for c = 1 : (size(A,2)/2) + 1
if A(:,c) == 0
A(:,c) = [];
end
end
%State final answer
Anew = A;
end
Please note that there may be a more efficient code solution, but I have never studied computer science (not my engineering discipline), so I don't know any fancy stuff.
Indexing will stop at the greatest possible value. So indexing x=1:2:4 will generate x = [1 3]. x=1:2:1 will generate x = 1. So now you just need to figure out how many elements are in each matrix row and column.
Pro-Tip: everywhere possible in any code you write, use the length() function for indexing. With the code below, A can be any size matrix. This prevents needing to change your code when you change the matrix you want to analyze.
for row=1:2:length(A(:,1))
for col=1:2:length(A(1,:))
% do some operation on A(row,col)
end
end
QUESTION
I'm looking for an elegant way to multiply two arrays along one particular dimension.
SIMILAR QUESTION
There is already a similar question on the official matlab forum, but the thread is outdated (2004).
EXAMPLE
M1 a [6x4x4] matrix and M2 a [6x1] matrix, I would like to multiply (element by element) M1 with M2 along the 3rd dimension of M1 to obtain a matrix M [6x4x4]
An equivalent to:
M1 = rand(6,4,4);
M2 = rand(6,1);
for ii = 1:size(M1,2)
for jj = 1:size(M1,3)
M(:,ii,jj) = M1(:,ii,jj).*M2;
end
end
VISUAL EXAMPLE
Do you know a cool way to do that ? (no loop, 1 or 2 lines solution,...)
If I'm interpreting your question correctly, you want to take each temporal slice (i.e. 1 x 1 x n) at each spatial location in M1 and element-wise multiply it with a vector M2 of size n x 1. bsxfun and permute are perfect for that situation:
M = bsxfun(#times, M1, permute(M2, [2 3 1]));
This question already has answers here:
How to generate the first twenty powers of x?
(4 answers)
Closed 7 years ago.
I have 1000 matrices with dimensions 2x2.
What I now need to do is to get 30 consecutive powers of those matrices (A^2, A^3... ...A^30) and store them all.
I found a topic that suggested using bsxfun:
Vectorizing the creation of a matrix of successive powers
However, bsxfun does not work with cell arrays ("Error using bsxfun
Operands must be numeric arrays").
What can I do?
PS. A secondary question: once I have them, I want to plot 4 graphs (each corresponding to 1 of the elements of the 2x2 matrices) with 30 positions (x-axis) which will show confidence bands (16th and 84th percentile).
EDIT: Someone linked to a question that was similar to the one that I linked. From what I can understand, the question there is about a vector, not array of matrices.
Assuming your array A is 2-by-2-by-1000, here are two loops to make things work:
A = rand(2,2,1000);
K = 30;
%%
N = size(A,3);
APower = zeros(2,2,N,K);
APower(:,:,:,1) = A;
for i = 1:N
for k = 2:K
APower(:,:,i,k) = A(:,:,i)*APower(:,:,i,k-1);
%// Alternatively you could use:
%APower(:,:,i,k) = A(:,:,i)^k;
end
end
You need to replicate the matrix 30 times to do this using cellfun. For example,
a = repmat(A{1},1,30);% Select one of your A matrices
b = num2cell(1:30);
x = cellfun(#(a,b) a^b,a,b,'UniformOutput',false)
Since you need to run cellfun for each element of A another way is to use arrayfun as below.
a = A{1};
b = 1:30;
x = arrayfun(#(b) a^b,b,'UniformOutput',false)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Interesting thought question for you guys. Given an array of length n, if I were to pick two random indexes in this array, a and b on average how far apart would they be? As in how many steps would I have to take to walk from a to b. There are no restrictions so there's a chance I pick the same index for both, and there's a chance a and b are at opposite ends of the array.
I've thought about this for a while, my initial idea being they're on average n/2(ish) apart, but I think this hunch is incorrect. An index chosen in the center of the array at most would have to walk n/2 places to find its corresponding second choice, whereas only at the ends of the array would the second choice ever be around n distance away.
Thanks!
After scribbling some grids of possible distances for the first few values of n, I think the exact result is in fact given by:
f(n) = (n² - 1) / 3n
Choosing two places in an array is equivalent to splitting the array up into 3 sections. The average size of each of those sections will be n/3 so the average distance between the two points is also n/3.
Using a monte carlo method in python:
from collections import defaultdict
import random
sample = [abs(random.choice(range(0,10)) - random.choice(range(0,10))) for i in range(0,10000)]
avg = float(sum(sample) / len(sample))
print ("Average: %f" % avg)
freq = defaultdict(int)
for s in sample:
freq[s] += 1
scale = 40.0 / max(freq.values())
for i in range(0,10):
print ("%d : %s" % (i, "#" * int(freq[i] * scale)))
Output:
Average: 3.293700
0 : ######################
1 : ########################################
2 : ####################################
3 : ###############################
4 : ##########################
5 : ######################
6 : #################
7 : #############
8 : #########
9 : ####
So, looks like it's n/3 - but it's not evenly distributed.
There is an easy way to know: for all the couples (a, b), computer their distance. Knowing that all the couples (a, b) have the same probability of appearance, you will just need to do the average of those distances in order to answer your question.