I had a weird experience with Matlab. I wanted to compute the time needed for matrices multiplication as follows:
tic;
for i=1:10^-3:10^4
[1 1 1]*[1 1 1;1 1 1;1 1 1];
end
toc;
and
tic;
for i=1:10^-3:10^4
[1 1 1;1 1 1;1 1 1]*[1 1 1;1 1 1;1 1 1];
end
toc;
now the result for first one was
Elapsed time is 7.707570 seconds.
so I expected the second one to be as 23 seconds (since the first one needs n^2=9 multiplications while the second one needs n^3=27) but the result was:
Elapsed time is 10.558797 seconds.
can someone explain to me what happened here?
Thanks
Related
I have got the following code. I need to rewrite it without looping. How should I do it?
l1 = [1 2 3 2 1];
l2 = [3 4 4 5 4];
A = zeros(5,5);
for i=1:5
A(i, l1(i):l2(i)) = 1;
end
A
You can use bsxfun -
I = 1:5 % Array corresponding to iterator : "for i=1:5"
out = bsxfun(#le,l1(:),I) & bsxfun(#ge,l2(:),I)
If you need a double datatype array, convert to double, like so -
out_double = double(out)
Add one more into the mix then! This one simply uses a cumsum to generate all the 1s - so it does not use the : operator at all - It's also fully parallel :D
l1 = [1 2 3 2 1];
l2 = [3 4 4 5 4];
A = zeros(5,5);
L1 = l1+(1:5)*5-5; %Convert to matrix location index
L2 = l2+(1:5)*5-5; %Convert to matrix location index
A(L1) = 1; %Place 1 in that location
A(L2) = 1; %Place 1 in that location
B = cumsum(A,1) ==1 ; %So fast
Answer = (A|B)'; %Lightning fast
Answer =
1 1 1 0 0
0 1 1 1 0
0 0 1 1 0
0 1 1 1 1
1 1 1 1 0
Here is how you could build the matrix without using a loop.
% Our starting values
l1 = [1 2 3 2 1];
l2 = [3 4 4 5 4];
% Coordinate grid of the right size (we don't need r, but I keep it there for illustration)
[r,c] = ndgrid(1:5);
% Build the logical index based on our lower and upper bounds on the column indices
idx_l1=bsxfun(#ge,c,l1');
idx_l2=bsxfun(#le,c,l2');
% The result
A = zeros(size(idx_l1));
A(idx_l1&idx_l2)=1
You may need something like [r,c] = ndgrid(1:numel(l1),1:10).
Also if your matrix size is truly huge and memory becomes an issue, you may want to stick to a loop anyway, but for 'normal size' this could be faster.
There should be some skepticism in every vectorization. If you measure the time actually your loop is faster than the given answers, mostly because you only perform in place write.
Here is another one that would probably get faster for larger sizes but I haven't tested:
tic
myind = [];
for i = 1:5
myind = [myind (5*(i-1))+[l1(i):l2(i)]];
end
A(myind) = 1;
toc
gives the transposed A because of the linear indexing order.
This question looks relatively simple, but I can't seem to find the running time in terms of n.
Here is the problem:
j = n;
while(j >= 2) {
j = j^(1/2)
}
I don't really need the total running time, I just need to know how to calculate the amount of times the second and third lines are hit (they should be the same). I'd like to know if there is some sort of formula for finding this, as well. I can see that the above is the equivalent of:
for(j = n; n >= 2; j = j^(1/2)
Please note that the type of operation doesn't matter, each time a line is executed, it counts as 1 time unit. So line 1 would just be 1 time unit, line 2 would be:
0 time units if n were 1,
1 time unit if n were 2,
2 time units if n were 4,
3 time units if n were 16, etc.
Thanks in advance to anyone who offers help! It is very much appreciated!
Work backwards to get the number of time units for line 2:
time
n n log_2(n) units
1 1 0 0
2 2 1 1
4 4 2 2
16 16 4 3
16^2 256 8 4
(16^2)^2 65536 16 5
((16^2)^2)^2) ... 32 6
In other words, for the number of time units t, n is 2^(2^(t-1)) except for the case t = 0 in which case n = 1.
To reverse this, you have
t = 0 when n < 2
t = log2(log2(n)) + 1 when n >= 2
where log2(x) is known as the binary logarithm of x.
Can someone please help me figure out how we reach to (n-1)/4+1 here
Let's say you have a loop from 1 to 10. So how many iterations are there?
(10 - 1) + 1 = 10 ==> (n-1) + 1
Actually you always add 1 to such calculations for the first iteration because if you start from 1 to 1 you still do one iteration and it doesn't matter if you increment the iterator by 1, by 2 or by 100.
Now let's assume that our iterator is incremented by 4 each time instead of by 1. So how many iterations are there now? You start from 1, then 5 and then 9... 3 iteration. We have (10-1) as previously but now only each 4th number is counted so it becomes (10-1)/4:
[(10 - 1)/4] + 1 = 3 ==> [(n-1)/4] + 1 (casting to the lower integer)
Is there any command in GNU Octave that allows me to count the zero (without counting the nonzero) entries in a matrix?
There are may ways, I'll show you two below.
a = rand (5,5) > 0.5
a =
0 0 0 1 1
1 1 0 1 0
0 1 0 1 1
0 0 0 1 0
1 1 0 1 1
numel (find (a==0))
ans = 12
This is faster for very large matrices (see below)
numel (a) - nnz (a)
ans = 12
Speed test for large matrices:
a = rand (1e6, 1e6) > 0.5;
tic
numel (find (a==0))
toc
tic
numel (a) - nnz (a)
toc
which gives
ans = 499566
Elapsed time is 0.060837 seconds.
ans = 499566
Elapsed time is 0.0187149 seconds.
Assume matrix M:
1 2 3
3 5 6
6 8 9
How do I store I extract the following row vector a from it?
1
5
9
You just need to use diag:
octave-3.4.0:1> A = [ 1 2 3; 3 5 6; 6 8 9 ]
A =
1 2 3
3 5 6
6 8 9
octave-3.4.0:2> D = diag(A)
D =
1
5
9
Note that you can also extract other diagonals by passing a second parameter to diag, e.g.
octave-3.4.0:3> D = diag(A, 1)
D =
2
6
octave-3.4.0:4> D = diag(A, -1)
D =
3
8
If you know the dimensions of your matrix (square or otherwise), you can extract any diagonal you like, or even modified diagonals (such as numbers in (1,1), (2,3), (3,5), etc), somewhat faster than using diag, by simply using an index call like this:
a=M(1:4:9)
(note: this produces a row vector; for a column vector, just transpose) For an NxN matrix, simply start at the desired value (1 for the top-left corner, 2 for next one down vertically, and so on), then increment by N+1 until you reach the appropriate value.
octave:35> tic; for i=1:10000 diag(rand(3)); end; toc;
Elapsed time is 0.13973 seconds.
octave:36> tic; for i=1:10000 rand(3)(1:4:9); end; toc;
Elapsed time is 0.10966 seconds.
For reference:
octave:49> tic; for i=1:10000 rand(3); end; toc;
Elapsed time is 0.082429 seconds.
octave:107> version
ans = 3.6.3
So the overhead for the for loop and the rand function, subtracted off, shows that using indices is about twice as fast as using diag. I suspect that this is purely due to the overhead of calling diag, as the operation itself is very straightforward and fast, and is almost certainly how diag itself works.