Eigen L How can I compute the inner product of a row vector from a sparse matrix and a dense vector? What is the efficiency? - sparse-matrix

SparseMatrix SM;
MatrixXd f;
SM is a m*n sparse Matrix(0.18%), and f is a n*1 column vector.
I want to get the ith row vector of SM and product it with f. How should I write the code?
I was also worried about the efficiency. As many redundant zeros may be involved in computation.

If SM is a column major matrix, then indexing one its row is very inefficient and essentially a no-go if performance matter. If SM is row-major, then you can simply do SM.row(i).dot(f), and the cost will be in the order of the number of non zeros in SM.row(i).

Related

Generating random vector that's linearly independent of a set of vectors

I'm trying to come up with an algorithm that will allow me to generate a random N-dimensional real-valued vector that's linearly independent with respect to a set of already-generated vectors. I don't want to force them to be orthogonal, only linearly independent. I know Graham-Schmidt exists for the orthogonalization problem, but is there a weaker form that only gives you linearly independent vectors?
Step 1. Generate random vector vr.
Step 2. Copy vr to vo and update as follows: for every already generated vector v in v1, v2... vn, subtract the projection of vo on vi.
The result is a random vector orthogonal to the subspace spanned by v1, v2... vn. If that subspace is a basis, then it is the zero vector, of course :)
The decision of whether the initial vector was linearly independent can be made based on the comparison of the norm of vr to the norm of vo. Non-linearly independent vectors will have a vo-norm which is zero or nearly zero (some numerical precision issues may make it a small nonzero number on the order of a few times epsilon, this can be tuned in an application-dependent way).
Pseudocode:
vr = random_vector()
vo = vr
for v in (v1, v2, ... vn):
vo = vo - dot( vr, v ) / norm( v )
if norm(vo) < k1 * norm(vr):
# this vector was mostly contained in the spanned subspace
else:
# linearly independent, go ahead and use
Here k1 is a very small number, 1e-8 to 1e-10 perhaps?
You can also go by the angle between vr and the subspace: in that case, calculate it as theta = arcsin(norm(vo) / norm(vr)). Angles substantially different from zero correspond to linearly independent vectors.
A somewhat OTT scheme is to generate a NxN non-singular matrix, and use it's columns (or rows) as the N linearly independent vectors.
To generate a non=singular matrix one could generate it's SVD and multiply up. In more detail:
a/ generate a 'random' NxN orthogonal matrix U
b/ generate a 'random' NxN diagonal matrix S with positive numbers in the diagonal
c/ generate a 'random' NxN orthogonal matrix V
d/ compute
M = U*S*V'
To generate a 'random' orthogonal matrix U, one can use the fact that every orthogonal matrix can be written as a product of Household relectors, that is of matrices of the form
H(v) = I - 2*v*v'/(v'*v)
where v is a non zero random vector.
So one could
initialise U to I
for( i=1..N)
generate a none zero vector v
update: U := H(v)*U
Note that if all these matrix multiplications become burdonesome, one could write a special routine to do the update of U. Applying H(v) to a vector u is O(N):
u -> u - 2*(h'*u)/(h'*h) * h
and so applying H to U can be done in O(N squared) rather than O( N cubed)
One advantage of this scheme is that one has some control over 'how linearly independent' the vectors are. The product of the diagonal elements is (up to sign) the determinant of M, so that if this product is 'very small' the vectors are 'almost' linearly dependent

Multiplying array columns by vector

I'm new to R and I am certain that this is simple yet I can't seem to find an answer. I have an array [36,21,12012], and I need to multiply all of the columns by a vector of the same length to create a new array of the same dimensions.
If v is your vector and a is your array, in your case it would be as simple as v * a, because arrays are built column-wise. But in general, you would use sweep. For example to multiply along the rows, sweep(a, MARGIN=2, STATS=v, FUN='*').

How to store vector coordinates in Matlab

what's the best way to store vector coordinates in Matlab?
For example, h is the height of the image, w is the width, how can I do this (pseudocode):
vectors = [];
for i=1:h
for j=1:w
vectors += p(i,j);
end
end
To get the kth p object from vectors, I can use vector(k).
Thank you very much.
Array growth in MATLAB works by indexing past the last element:
vectors(end+1) = p(i,j);
Conventional wisdom is that it is better to pre-allocate your array and use indexing, but automatic array growth has become much more efficient, especially for cells and arrays of non-builtin objects.
However, you can just get what you want out of p directly via [ii,jj] = ind2sub(size(p),k); p(jj,ii). Note the order jj,ii to match your loop semantics, which would create a vector that indexes the elements of p in a row-major order vs. MATLAB's native column-major ordering. That is, p(2) refers to row 2, column 1 of p, but your vectors(2) would contain to row 1, column 2 of p using your loop order.
You can use p(k) directly. It is equivalent to p(i,j) where [i,j] = ind2sub([h w], k).
Documentation for ind2sub
Unless I didn't understand your question…

Should arrays be thought of as horizontal or vertical structures

I am working on some Matlab homework and I was having issues conceptualizing the way that it addresses matrices. In Matlab the matrix is address in d(row,col) format.
I have been programming for a while and have always tended to think of a one dimensional array as a horizontal structure with a second dimension extending out from below.
Which of these is a "more correct" way of thinking about an array data structure from the computer's point of view
Good question +1.
Purely from a Matlab programming perspective, it is best to think of a matrix as a sequence of column vectors. Why? Because this is how Matlab allocates them to your computers memory. That is, two sequential elements in any given column of a matrix will be allocated next to each other in memory. This is sometimes referred to as "column-major order", and is used in languages such as Fortran, R, and Julia. The opposite is, unsurprisingly, called "row-major order", and is used in C and Python.
The implication of this is that Matlab will be much faster at performing operations on the columns of a matrix than on the rows. #angainor provided a great answer to a question of mine a few months ago that demonstrates this fact. Based on #angainor's insight, here is a useful speed test to run:
M = 1000; %# Number of iterations over each method
T = 1000; %# Number of rows
N = 1000; %# Number of columns
X = randn(T, N); %# Random matrix
%# Loop over the rows of a matrix and perform a sum operation on each row vector
tic
for m = 1:M
for t = 1:T
sum(X(t, :));
end
end
toc
%# Loop over the columns of a matrix and perform a sum operation on each column vector
tic
for m = 1:M
for n = 1:N
sum(X(:, n));
end
end
toc
On my machine, the outcome of the test is:
Elapsed time is 9.371870 seconds. %# Looping over rows
Elapsed time is 1.943970 seconds. %# Looping over columns
In other words, operations performed on columns are almost 5 times faster than operations performed on rows!
From a mathematical perspective I don't trust myself to give a good answer. You could probably get some great insights from math.stackexchange.

Simple explanation of PCA to reduce dimensionality of dataset

I know that PCA does not tell you which features of a dataset are the most significant, but which combinations of features keep the most variance.
How could you use the fact that PCA rotates the dataset in such a way that it has the most variance along the first dimension, second most along second, and so on to reduce the dimensionality of the dataset?
I mean, more in depth, How are the first N eigenvectors used to transform the feature vectors into a lower-dimensional representation that keeps most of the variance?
Let X be an N x d matrix where each row X_{n,:} is a vector from the dataset.
Then X'X is the covariance matrix and an eigen decomposition gives X'X=UDU' where U is a d x d matrix of eigenvectors with U'U=I and D is a d x d diagonal matrix of eigenvalues.
The form of the eigendecomposition means that U'X'XU=U'UDU'U=D which means that if you transform your dataset by U then the new dataset, XU, will have a diagonal covariance matrix.
If the eigenvalues are ordered from largest to smallest, this also means that the average squared value of the first transformed feature (given by the expression U_1'X'XU_1=\sum_n (\sum_d U_{1,d} X_{n,d})^2) will be larger that the second, the second larger than the third, etc.
If we order the features of a dataset from largest to smallest average value, then if we just get rid of the features with small average values (and the relative sizes of the large average values are much larger than the small ones), then we haven't lost much information. That is the concept.

Resources