Monday, September 21, 2009
Windows: Atbroker.exe failure workaround.
Atbroker.exe - Application Error in Vista
Quote:
"a workaround for now is to do CTRL-ALT-END and choose Logoff."
Monday, July 27, 2009
Matlab: grouping values according to ID
Q:
If we have n x 2 matrix x:
x = [11 19; 11 29; 10 34; 7 189; 6 123; 11 18; 21 182; 3 171; 6 145; 7 111]
Where the first column specifies the group ID and we want to break up the 2nd column into a cell array according to the grouping ID.
The desired output is:
c = {[171]; [145; 123]; [189; 111]; [34]; [18; 29; 19]; [182]}
A:
[u,dump,g] = unique(x(:,1))
c = accumarray(g,x(:,2),[length(u),1],@(x){x})
Matlab: handling nan for findstr
For example, if I have vector
x = [1 2 3 nan 5 6 nan nan 9 10 11 12 nan 14]
If I want to locate 2 consequtive NaNs, I may use a combination of find, isnan, and diff.
However, what if I want to locate a subvector that also contains NaN? For instance, how to find
y = [3 nan 5]
in x?
If y does not contain NaNs, we know we can use findstr.
The straitforward solution is to convert NaNs to some value that doesn't appear in y.
For example,
sudoNan = max(x)+1;
x(isnan(x)) = sudoNan;
y(isnan(y)) = sudoNan;
findstr(x,y)
An even easier method is:
xc = typecast(x,'uint64');
yc = typecast(y,'uint64');
findstr(xc,yc)
Matlab: grouping and add up values according to ID
Q:
Suppose I have n x 3 matrix x, I want a piece of code that checks the first and second columns and if they are equal then it adds up the correponding values in the third column.
x = [
1 2 3; 1 2 5; 1 2 3;...
1 3 1; 1 3 1; 2 1 1;...
2 1 1; 2 1 2; 2 1 2]
The desired answer should be
y = [
1 2 11; 1 3 2; 2 1 6]
A:
[val, dump, idx] = unique(x(:,1:2),'rows')
y = [val, accumarray(idx,x(:,3))]
Matlab: fast way to insert zeros into a vector
Q:
Suppose I have vector
x = [1 2 3 4 5 6 7]
How do I insert zeros at every 3rd position to obtain
y = [1 2 0 3 4 0 5 6 0 7]
A1:
y = zeros(1,floor(length(x)*1.5));
z = 1:length(x);
y(z+ceil(z/2)-1) = x;
Matlab: indexing matrix of unknown number of dimensions
Q:
If I know a multidimensional matrix x has 4 dims, I can index the first "row" of x using
x(1,:,:,:)
but how do I do this if I don't know ndims beforehand?
A:
c(1:ndims(x)-1)={':'};
x(1,c{:})
Matlab: counting zeros neighbouring each element
I have matrix x, I want to count for each element the number of zeros in the neighbouring 8 element.
For example, if
x = [
1 0 0
0 1 1
0 1 0];
I want to obtain count
c = [
2 2 1
2 5 3
1 3 0];
A:
c = conv2([1 1 1; 1 0 1; 1 1 1],double(~x),'same');
OR
c = conv2([1 1 1],[1 1 1],double(~x),'same')-~x;
Saturday, July 25, 2009
Matlab: optimization
Q:
Is there a way to optimize this for loop?
f = 0;
for i = 1:n
for j = i+1:n
z = y(i) - y(j) ;
f = f + z*z ;
end
end
f = 2*f;
A1:
yy = meshgrid(y);
f = sum(sum((yy - yy.').^2));
A2:
Assuming y is column vector:
f = 2*((n+1)*sum(y.^2)-2*cumsum(y')*y);
A little bit explanation:
Suppose
y = [y1 y2 y3 y4]
f =
(y1-y2).^2 + (y1-y3).^2 + (y1-y4).^2 +
(y2-y3).^2 + (y2-y4).^2 +
(y3-y4).^2
=
y1y1+y2y2-2*y1y2 + y1y1+y3y3-2*y1y3 + y1y1+y4y4-2*y1y4 +
y2y2+y3y3-2*y2y3 + y2y2+y4y4-2*y2y4 +
y3y3+y4y4-2*y3y4
=
y1y1 + y1y1 + y1y1 +
y2y2 + y2y2 + y2y2 +
y3y3 + y3y3 + y3y3 +
y4y4 + y4y4 + y4y4 - 2*(
y1y2 + y1y3 + y1y4 + y2y3 + y2y4 + y3y4
)
=
3*sum(y.^2) - 2*(
(y1).*y2
(y1+y2).*y3
(y1+y2+y3).*y4
)
Friday, June 19, 2009
Tuesday, June 16, 2009
Matlab: find row vector within matrix.
Q:
Say I have a matrix:
x = [
11 22 33
44 55 66
11 11 11
33 99 33
11 77 23]
I want to find a specific row in it, say y = [11 11 11].
A1:
You can use ismember with parameter "rows".
A2:
To allow some tolerance:
% engine;
locrow = @(A,x,tol)find(sum(abs(bsxfun(@minus,A,x)),2) <= tol)
% usage;
tol = 0.01
locrow(A,[11.0001, 11.0001, 10.9999], tol)
Matlab: vectorize a loop that depends on past info.
Q:
Can anybody think of a vectorized solution to the problem below? suppose x(1) ~= 0;
for k = 2:length(x)
if x(k) == 0
x(k) = x(k-1);
end
end
A:
y = find(x);
x1 = x(y(cumsum(x ~= 0)));
Note:
In most cases the for-loop is probably 3-4 times faster than the vectorized code.
Matlab: vector indexing.
Q:
I have a random vector r of size 50000 x 1, and a strictly decreasing measuring vector d of size 300 x 1. I want for each element in r, find the indices of the first value in d that is smaller than it. I tried these codes but it is too slow. Is there a vectorized solution?
n = 50000;
r = rand(n,1);
d = linspace(1,0,300);
idx = nan(n,1);
for k = 1:n
idx(k) = find(r(k) > d, 1, 'first');
end
A:
[dump,idx] = histc(r,d(end:-1:1));
idx = length(d)-idx+1;
Wednesday, June 10, 2009
Matlab: break consecutive numbers into cells
Q:
Suppose I have a sorted array like
[1 2 3 4 5 10 11 17 18 19]
I want to break consecutive blocks into separate arrays:
[1 2 3 4 5]
[10 11]
[17 18 19]
A:
mat2cell(x,1,diff([0,find(diff(x) ~= 1),length(x)]))
Tuesday, June 09, 2009
Matlab: find 5 consecutive numbers in an array
Q:
I want to find blocks of values of ascending order within a vector. e.g.:
[... 10 1 2 3 4 5 56 ...]
and [1 2 3 4 5] should be recognized.
it should also recognise e.g.:
[... 100 50 51 52 53 54 20 ...]
A:
% if not care about precisely 5 number block;
strfind(diff(x), [1 1 1 1])
% if has to be 5 consecutive number;
strfind(diff(x) == 1,[0 1 1 1 1 0])+1
Thursday, May 21, 2009
Matlab: Vector indexing;
Q:
Suppose I have a vector like: v = [ 3 2 4 1 3 2...]
I want to obtain a new vector like: w = [3 3 3 2 2 4 4 4 4 1 3 3 3 2 2...]
basically every value repeates it's own number of times.
A1 (one-liner):
w = cell2mat(arrayfun(@(x) x+zeros(1,x), v, 'uni', 0))A2:
v(v == 0) = [] % Need to get rid of zeros in the general case.Speed test:
c = cumsum(v)
w = zeros(1,c(end))
w([1,c(1:end-1)+1]) = 1
w = v(cumsum(w))
% v = randi(800,1,90000)+1;
Method 1:
Elapsed
time is 1.997060 seconds.
Method 2:
Elapsed time is 1.630775 seconds.
Two methods are about same speed.
Wednesday, May 20, 2009
Matlab: vector indexing;
Q:
I have a reference vector r, and a target vector v, I want to find, for every element in v, the index of first element that is greater than or equal to it in r.
With a for loop it shall look like this:
for k = 1:length(r), idx(k) = find(r >= v(k), 1, 'first'); endA1 (the 'standard' vectorization):
[dummy,idx] = max(bsxfun(@ge,r(:),v(:).'));
A2 (interesting):
idx = ceil(interp1(r,1:length(r),v));
A3 (same logic as A2 but better):
[dummy, idx] = histc(v,r);
idx = idx+1;
Speed test:
% r = cumsum(rand(100000,1));
% r = r./r(end);
% v = rand(20000,1);
Method 1: % actually slower than the for loop ... memory.
Elapsed time is 6.582422 seconds.Method 2:
Elapsed time is 0.015725 seconds.Method 3:
Elapsed time is 0.006501 seconds.The For loop:
Elapsed time is 4.209633 seconds.
Wednesday, May 13, 2009
Matlab: indexing; find first value in each row
Q:
How can I find the first index of certain value in each row without using a for loop?
A1:
m = round(rand(9,4)*3); % the data;
[r,c] = size(m);
n = 3; % number to find.
idx = mod(sum(cumprod(double(m ~= n),2),2)+1,c+1)
A2:
idx = zeros(size(m,1),1);
tmp = m == n;
[r,c] = find(tmp & cumsum(tmp,2) == 1);
idx(r) = c;
A3 (fastest):
[v,idx] = max(m == n,[],2)
idx = idx.*(v==1);
% or idx(v==0) = 0;
Speed test:
% m = round(rand(1600000,4)*3);
A1:
Elapsed time is 0.293340 seconds.
A2:
Elapsed time is 0.407424 seconds.
A3:
Elapsed time is 0.110964 seconds.
Matlab: matrix indexing; find duplicate entries in a matrix and replace them with average
Q:
I've got a matrix of integer values with three columns (X,Y,Z) and about 10k rows.
X and Y are in range 0..1000 and Z is in the range of 0..200.
In this matrix, there are some pairs of (X,Y) that occur more than once, but with different Z values. Now I want to remove these duplicates and replace all of them with (X,Y,mean of Z).
A:
[u,id1,id2] = unique(A(:,1:2),'rows');
B = [u,accumarray(id2,A(:,3))./accumarray(id2,1)];
% or accumarray(id2,A(:,3),[],@mean) but this is much slower.
Speed test:
% A = [round(rand(10000,2)*1000),round(rand(10000,1))*200];
Elapsed time is 0.005959 seconds.
Monday, May 11, 2009
Matlab: Block randomization
[3 1 2 2 1 3 1 3 2 1 3 2 1 2 3 2 3 1]
Basically random perm is performed within every size-3 block.
Here's a tip to do this in matlab in one line:
[dump,idx] = sort(rand(nCondition,nTrial));
Matlab: Vector operation
Q:
Is there a vectorized way for this code?
for i=1:size(m,2)
m(:,i) = m(:,i).*v(i);
end
A1:
mv = bsxfun(@times,m,v');
A2:
mv = m*diag(v);
all these solutions are much better than using repmat etc.
Matlab: Matrix Indexing
Q:
Suppose I have a 3D matrix A:
A(:,:,1) =
[0.1, 0.2, 0;
0.2, 0, 0;
0.6, 0.4, 0]
A(:,:,2) =
[0.2, 0.7, 0;
0.3, 0.8, 0;
0.1, 0, 0]
I want to find, for each row, the element before the first occurrence of zero and subtract it from 1. The outcome should look like this:
B(:,:,1) =
[0.1, 0.8, 0;
0.8, 0, 0;
0.4, 0.6, 0]
B(:,:,2) =
[0.2,0.3,0;
0.3, 0.2, 0;
0.9, 0, 0]
A1:
% location of first occurrence of zero in each row.
z = cumsum(A == 0,2) == 1;
% the element before it.
y = circshift(z,[0,-1]);
B = A;
B(y) = 1-B(y);
A2 (a beautiful solution):
% convolution along columns.
y = convn(logical(A),[-1 1],'same') > 0;
B = A;
B(y) = 1-B(y);
Friday, May 08, 2009
Tuesday, May 05, 2009
Matlab: Vectorization.
Q:
I have
c = cell(n,1); % Each cell is an array of integers.
How do you vectorize this loop? it takes very long.
for i=1:n-1
for j=i+1:n
lic(i,j)=length(intersect(c{i},c{j}));
end
end
A1:
Generate some data for testing:
the data:
n=200; % number of sets
m=100; % element value are from 0 to m-1
meannumel=50; % average number of elements in lists
s = 20; % standard deviation of number of elements
c=cell(1,n);
for k=1:n
nelk = meannumel+round(s*randn);
nelk = min(max(nelk,1),m);
c{k} = floor(m*rand(1,nelk));
end
The engine:
n = length(c);
c = cellfun(@(x) unique(x(:)), c, 'uni', false);
s = cumsum([1 cellfun(@length,c)]).'; % boundary of cell, in vector x;
x = cat(1,c{:}); % all elements, in one long vector;
[x,p] = sort(x); % x is sorted now;
u = cumsum([1;diff(x) ~= 0]);
% before cumsum: boundary of unique (different) elements in x; cumsum: to get a vector u, so that u = 11111223333, # of index equal to count of value;
t = cumsum(accumarray(s,1));
% accumarray: here equal to tmp = zeros(s(end),1); tmp(s) = 1; cumsum: to get a vector t, so that t = 1111222223333 # of index equal to count of that value. here s is boundary of cell, so this t is actually which cell each element belongs;
A = sparse(u,t(p),1,u(end),n);
% sparse: only store non-zero elements, save memory space; syntax: p = sparce(i,j,s,m,n) will create a m x n sparse matrix, with elements p(i(k),j(k)) = s(k); here the intention is to add 1 at, the unique element index, vs. the cell index that each elements belongs.
% A is in the format of: unique item index by which cell, here A is essentially a logical matrix (valued 0, 1 only)
A = triu(full(A'*A),1);
% A'*A is the trick to count intersected values; colums and rows in A are only 1 or 0. matrix muptiplication sums the ones.
A2:
A2 is slightly improved over A1 in that the 'unique' is only called once.
% c must be a list of *row* vectors
[dummy dummy cmap] = unique([c{:}]);
% length(dummy) is the number of unique values in c. cmap is in the form of [1 2 3 1 1 2 2 2 4 ...], which specifies unique values indeces in [c{:}]. length(cmap) = numel([c{:}];
nele = cellfun(@length,c(:));
setid = cumsum(accumarray(cumsum([1; nele]),1));
A = sparse(setid(1:end-1),cmap(:),1,length(c),length(dummy));
A = spones(A); % SPONES Replace nonzero sparse matrix elements with ones.
A = triu(full(A*A.'),1);
Speed comparison:
The for loop: 3.55 sec.
A1: 0.022 sec.
A2: 0.015 sec.
Matlab: Vector manipulation.
Q:
Suppose I have
p = [ 0.81 0.90 0.12 0.91 0.63 0.09 0.27 0.54 0.95 0.96 0.15 0.97 0.95 0.48 0.80 0.14 0.42 0.21 0.54 0.14];
v = [ 1 0 0 1 0 1 0 1 1 1 1 1 0 0 0 0 1 1 0 1];
Where the 1 defines the boundary of blocks. So the first block is 1 0 0, second 1 0, third 1 0, fourth 1, fifth 1, ... and so on.
I want to sum values in p according to blocks defined by v. The output in this case should look like:
r = [1.83 1.54 0.36 0.54 0.95 0.96 0.15 3.34 0.42 0.75 0.14];
A:
r = accumarray(cumsum(v(:)),p(:))
Matlab: Vector indexing;
Suppose I have a vector:
x = [1 1 1 1 2 2 2 8 8 8 8 8 8 0 0 9 9 7 5 5 2 2 2 2 2]
I want to obtain:
b = [1 2 3 4 1 2 3 1 2 3 4 5 6 1 2 1 2 1 1 2 1 2 3 4 5]
Basically each block of integer is replaced by continuous index of the count.
Solution:
Some initial processing to detect block size and locations:
y = find([true;diff(x(:)) ~= 0;true]);
c = diff(y);
v = x(y(1:end-1));
method 1:
b = cell2mat(arrayfun(@(z)(1:z)',c,'uniformout',false));
method 2:
b = ones(size(x));
b(y(2:end-1)) = 1-c(1:end-1);
b = cumsum(b);
method 3:
g = (1:max(c))'*ones(1,numel(c));
b = g(bsxfun(@ge,c,1:max(c))');
Speed comparison:
% The testing data;
x = cell2mat(arrayfun(@(y,z)(y+zeros(1,z)), ...
randi(100,10000,1),randi(2000,10000,1),'uniformout',false));
% Method 1; 0.25 sec
% Method 2; 0.17 sec
% Method 3; 1.05 sec
Method 2 is better.
Matlab: Matrix Indexing
Q:
A = [
50 75 0;
50 0 100;
0 75 100;
75 100 0;
0 75 100;
0 75 100];
to
-1 75 0
-1 0 100
0 -1 100
-1 100 0
0 -1 100
0 -1 100
A1:
[I, J] = ind2sub(size(A), find(A ~= 0));
[b, c] = unique(I, 'first');
A(sub2ind(size(A), b, J(c))) = -1
A2:
B=cumsum(A~=0,2)>0
B=[false(size(B,1),1) B]
A(logical(diff(B,1,2))) = -1
A3:
A((cumsum(~~A, 2) == 1) & (A ~= 0)) = -1
% notice ~~A is equal to A ~= 0
DSP: How to understand convolution.
Definition from wikipedia:
The convolution of ƒ and g is written ƒ∗g. It is defined as the integral of the product of the two functions after one is reversed and shifted.
Let the unit response of a filter be denoted by u, and let x denote the input, y denote the output. Think of the input as the sum of many different delayed and scaled unit inputs:
t = [1, 2, 3, 4, ... n]
x = [x(1), 0, 0, 0, 0 ... 0]
+ [0, x(2), 0, 0, 0 ... 0]
+ [0, 0, x(3), 0, 0 ... 0]
+ ...
+ [0 ... 0, 0, 0, 0, x(n)]
then the output could be seen as the sum of responses to these unit inputs:
y = [u(1)*x(1), u(2)*x(1), u(3)*x(1) ... u(n)*x(1)]
+ [0, u(1)*x(2), u(2)*x(2), u(3)*x(2) ... u(n-1)*x(2)]
+ [0, 0, u(1)*x(3), u(2)*x(3), u(3)*x(3) ... u(n-2)*x(3)]
+ ...
+ [0, 0, ... 0, 0, u(1)*x(n)]
so at particular time n, the output takes the form of:
y(n) = u(n)*x(1) + u(n-1)*x(2) + u(n-2)*x(3) + ... + u(1)*x(n)
which explains why "flipping" is needed in convolution.
Matlab: Matrix manipulation.
Q:
I have the following matrix:
[1 5
4 9]
What's the fastest way, and without a for loop, to expand it to:
[1 1 5 5
1 1 5 5
4 4 9 9
4 4 9 9]
A1:
A = [1 4; 5 9] ;
kron(A, ones(3)) ;
A2:
idx = cumsum(ones(2),2 )
B = A(idx, idx)
A3:
[m, n] = size(A);
mdup = 4;
ndup = 3;
vx = ceil((1:m*mdup)/mdup);
vy = ceil((1:n*ndup)/ndup);
B = A(vx, vy)
A4:
[m,n] = size(A);
mdup = 4;
ndup = 3;
AX = repmat(A, [1 1 mdup ndup]);
AX = permute(AX, [3 1 4 2]);
AX = reshape(AX, m*mdup, n*ndup);
Monday, May 04, 2009
Matlab: Vector manipulation.
Q:
Suppose
a = [0 0 0 1 1 0 0 0 1 0 0 0 0 1 0 0 1 0 1 ];
I'd like to organize this vector into a matrix with the following criteria: every time I see a 1,
I want to copy that 1 and 2 other members before it into a new line, so my resulting matrix will look like this:
b = [
0 0 1
0 1 1
0 0 1
0 0 1
0 0 1
1 0 1];
Is there a vectorized solution?
A:
apad=[0 0 a];
i1 = find(apad == 1);
b = apad(bsxfun(@plus, i1(:), (-2:0)))
Matlab: Split a vector into continuous chunks.
Q:
Suppose I have [1 2 3 4 8 9 16 17 18], how do I get [1 2 3 4], [8 9], [16 17 18] in a vectorized way?
A:
a = [1 2 3 4 8 9 16 17 18];
b=a-(1:length(a));
b = [true; diff(b(:)) ~= 0; true];
split = mat2cell(a(:).', 1, diff(find(b)));
split{:}
Matlab: Automatic conversion to element-by-element operation.
Q:
Is there a function which automatically puts points in front of / , * or ^ in a formula?
e.g.
from
f = 3*sin(2*x^2)
to
f = 3.*sin(2.*x.^2)
A:
help vectorize
Matlab: Including function definitions when Publishing
I'm using MATLAB to generate a report from a script file, and was wondering if it's possible to somehow include function definitions which will be automatically be added to my published document. Instead of having to copy/paste between seperate published documents into a final one.
A:
help dbtype
Original post here.
Matlab: Product Support 1109 - Code Vectroization Guide
This section might be useful:
Suppose you want to multiply each column of a very large matrix by the same vector. There is a way to do this using sparse matrices that saves space and can also be faster than matrix construction...
F = rand(1024,1024);
X = rand(1024,1);
Y = F * diag(sparse(X));
Y = diag(sparse(X)) * F;
On the other hand, most of times bsxfun would be a more efficient solution.
Matlab: search via command line
docsearch Search HTML documentation in the Help browser.
Original post here.
Q:
Is there a general command in command window to display all conversion functions used in matlab, i.e. num2str, int2str, setstr, hex2num, ... etc?
A:
lookfor convert;
docsearch convert;
docsearch conversion;