Creating few columns of the Vandermonde matrix without using vander

16 visualizzazioni (ultimi 30 giorni)
Hi,
I want to create the first n columns of the Vandermonde matrix (I need this matrix in order to fit a curve through given points with the lsqlin function). Of course the commands:
A = vander(x);
A = A(1:n);
would do the work, but since the vector x might have over million values and n could be very small, 10 for example, it would be very inefficient.
I already did it with a for loop:
A = ones(length(x), n);
for i = 2 : n
A(:, i) = (x.^(i - 1));
end
but I think it can be done more elegant without a loop. Is there a function that does this? Or can someone give me an idea how to do it without a loop? I am thinking that repmat or reshape might be useful.

Risposte (3)

Jan
Jan il 8 Ago 2011
Modificato: Jan il 16 Ago 2017
You calculate the Vandermonde matrix from right to left. Is this intented? Do you want to get the n leftmost columns (smallest values)?
The power operation consumes a lot of time.
function A = ShortVander(x, n)
x = x(:); % Column vector
A = ones(length(x), n);
for i = 2:n
A(:, i) = x .* A(:, i-1); % [EDITED, Thanks Steven]
end
Look into the source code of VANDER to find a very equal approach...
  3 Commenti
Steven Morrow
Steven Morrow il 15 Ago 2017
Modificato: Steven Morrow il 15 Ago 2017
The multiplication should be compnenet-wise, i.e. the line in the for loop should be A(:,i) = x.*A(:,i-1)
Are Mjaavatten
Are Mjaavatten il 6 Apr 2022
This is nice, but why not let the built-in vander function take the number of columns as an optional second argument?

Accedi per commentare.


Aleksandar
Aleksandar il 8 Ago 2011
I just found a function that does this without any loops, just as I was looking for, and it is using repmat and cumprod:
  1 Commento
Jan
Jan il 8 Ago 2011
Modificato: Jan il 16 Ago 2017
Please compare the times with my posted FOR loop. Under Matlab 2009a and for x = rand(1, 1000) the CUMPROD method needs >50% more time. I've tried this version before I've posted the loop:
function A = ShortVander(x, n)
v = v(:);
A = v(:, ones(1, n));
A(:, 1) = 1;
A = cumprod(A);
But this is also about 50% slower than the loop. If you work with large arrays it has the additional problem, that it needs a lot of temporary memory.

Accedi per commentare.


Steven Lord
Steven Lord il 6 Apr 2022
You could do this pretty easily if you know the powers to which you want to raise the data used to create the Vandermonde matrix.
data = 1:6;
powers = [5 3 1];
V = vander(data)
V = 6×6
1 1 1 1 1 1 32 16 8 4 2 1 243 81 27 9 3 1 1024 256 64 16 4 1 3125 625 125 25 5 1 7776 1296 216 36 6 1
V2 = reshape(data, [], 1).^powers
V2 = 6×3
1 1 1 32 8 2 243 27 3 1024 64 4 3125 125 5 7776 216 6
The columns of V2 are the first, third, and fifth columns of V corresponding to data^5, data^3, and data^1.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by