Vectorizing the creation of a matrix of successive powers - matlab

Let x=1:100 and N=1:10. I would like to create a matrix x^N so that the ith column contains the entries [1 i i^2 ... i^N].
I can easily do this using for loops. But is there a way to do this using vectorized code?

I'd go for:
x = 1:100;
N = 1:10;
Solution = repmat(x,[length(N)+1 1]).^repmat(([0 N])',[1 length(x)]);
Another solution (probably much more efficient):
Solution = [ones(size(x)); cumprod(repmat(x,[length(N) 1]),1)];
Or even:
Solution = bsxfun(#power,x,[0 N]');
Hope this helps.

Sounds like a Vandermonde matrix. So use vander:
A = vander(1:100);
A = A(1:10, :);

Since your matrices aren't that big, the most straight-forward way to do this would be to use MESHGRID and the element-wise power operator .^:
[x,N] = meshgrid(1:100,0:10);
x = x.^N;
This creates an 11-by-100 matrix where each column i contains [i^0; i^1; i^2; ... i^10].

Not sure if it really fits your question.
bsxfun(#power, cumsum(ones(100,10),2), cumsum(ones(100,10),1))
EDIT:
As pointed out by Adrien, my first attempt was not compliant with the OP question.
xn = 100;
N=10;
solution = [ones(1,xn); bsxfun(#power, cumsum(ones(N,xn),2), cumsum(ones(N,xn),1))];

Why not use an easy to understand for loop?
c = [1:10]'; %count to 100 for full scale problem
for i = 1:4; %loop to 10 for full scale problem
M(:,i) = c.^(i-1)
end
It takes more thinking to understand the clever vectorized versions of this code that people have shown. Mine is more of a barbarian way of doing things, but anyone reading it will understand it.
I prefer easy to understand code.
(yes, I could have pre-allocated. Not worth the lowered clarity for small cases like this.)

Related

Using spfun with two identically ordered sparse matrices

I got two sparse matrices A and B, which have identical sparsity pattern (all nonzeros are at exactly the same locations):
i = randi(1000,[50,1]);
j = randi(1000,[50,1]);
a = rand(50,1);
b = rand(50,1);
A = sparse(i,j,a,1000,1000);
B = sparse(i,j,b,1000,1000);
I would like to calculate efficiently exp(A-B) only for the nonzeros, and save it back into A.
I tried to use spfun for that task:
f = #(x,y) exp(x-y);
A = spfun(f,A,B);
but I got an error in spfun saying: "Too many input arguments."
Can anyone suggest an efficient way to calculate it?
It should be calculated many times.
Thanks!
Edit: mikkola suggested A = spfun(#f,A-B) which solves the problem, but the question remains how to do it with a function of two variables that can't be solved using the same trick. For example:
g = #(x,y) x.*cos(y);
A = spfun(#g,A,B);
You can't use
A = spfun(#exp, A-B);
because for entries where A an B are equal you will get 0 instead of 1.
To solve that, you can compute the vector of exponentials at the nonzero components, and then build a sparse matrix from that:
A = sparse(i,j,exp(nonzeros(A)-nonzeros(B))); %// if you have i, j stored
or
A(find(A)) = exp(nonzeros(A)-nonzeros(B));
Edit
According to the documentation, spfun can take only two inputs: a function and one sparse matrix.
So you cannot do directly what you want to do. The best solution is probably what has been suggested in the comments, i.e.:
res = spfun(#exp, A-B);
Best,

Indexing of Matrices in Matlab

How can I merge this two commands in one in Matlab?
Temp = diag(diag(A));
X = Temp(:)
Something like
X = diag(diag(A))(:)
does not work.
If you really want to, you can do:
X = reshape(diag(diag(A)),[],1)
I'm not sure you gain much by doing that though!

Multiplying each element of a vector with a matrix

I have a vector v and a matrix M. I want to multiply each element of v with M and then sum all the resulting matrices.
for i=1:length(v)
lala(:,:,i) = v(i).*M;
end
sum(lala, 3)
Is it possible to do this without a for loop?
I think Danil Asotsky's answer is correct. He's exploiting the the linearity of the operation here. I just want to give another solution, using use the Kronecker tensor product, that does not dependent on this linearity property, hence still works with operation other than sum:
kvM = kron(v,M);
result = sum(reshape(kvM,[size(M) numel(v)]),3)
It's too late at my local time, and I dont feel like explaining the details of why this works, if you can't figure out from matlab help and wikipedia, then comment below and I'll explain for you.
Do you have single matrix M that don't depend from i?
In this case sum(v(i) * M) = sum(v(i)) *M.
E.g you will have expected result for code:
v_sum = sum(v);
lala_sum = v_sum * M;

Tabulated values's management in MATLAB

I have to build a function from tabulated values (two columns) which are written in a text file. The process to make it is the following:
Use the command importdata to read the data file
Xp = importdata('Xp.dat','\t',1);
Store each column in a variable
x = Xp(1:18304,1);
y = Xp(1:18304,2);
Make a curve fitting with both variables
ft = fittype('linearinterp');
datos.f_Xp = fit(x,y,ft);
However, when I am profiling the code I have found out that my bottleneck are the built-in functions fittype.fittype, fittype.evaluate, cfit.feval, ppval and cfit.subsref
which are related to the curve fitting. So I ask myself how I should manage the tabulated values for improving my code.
you're trying to fit 18304 data points to a curve. Also, you're using linearinterp... which means a routine is being run in a piecewise fashion. if you want to make the code faster use less datapoints.
Or perhaps try:
ft = fittype('poly1');
Not sure is it will be the answer you need as I don't have access to the data
May be "Eval" function could work in your case,
some simple example :
A = '1+4'; eval(A)
ans =
5
P = 'pwd'; eval(P)
ans =
/home/myname
and a bit more advanced!
for n = 1:12
eval(['M',int2str(n),' = magic(n)'])
end
Also, it has a sister name "feval"
guess, what does it do !
[V,D] = feval('eig',A)
[V,D] = eig(A)
and here
function plotf(fun,x)
y = feval(fun,x);
plot(x,y)
You are right ! all are equivalent,
check out here and find more relevant function

How to perform a checkerboard-interpolation in matlab?

I have two matrices A and B containing values for a checkerboard/chessboard-like grid of the form
AxAxAxAx...
xBxBxBxB...
AxAxAxAx...
xBxBxBxB...
...........
...........
Where x represents values not yet known which I want to (linearly) interpolate. What's the easiest way to achieve this?
First thing is probably
C = zeros(size(A)+size(B));
C(1:2:end,1:2:end) = A;
C(2:2:end,2:2:end) = B;
to obtain aforementioned matrix. Now I could loop through all remaining points and take the average of all direct neighbours, for 1) for loops in matlab are slow and 2) there's certainly a way to use interp2, though that seems to require a meshgrid-like grid. So, can this be done easier/faster?
Thanks to woodchips' answer here I found his inpaint_nans, the solution is indeed simple:
C = nan(size(A)+size(B));
C(1:2:end, 1:2:end) = A;
C(2:2:end, 2:2:end) = B;
C = inpaint_nans(C);