Related
I am using maxima, and I believe I have a simple question: How do I put the eigenvalues of a matrix in a list, so that I can compute the largest eigenvalue?
From what I'm reading, if M is a matrix, then eigenvalues(M) is a list containing two lists, the first is contains the eigenvalues of M, the second is a list of numbers representing their respective multiplicities. So I guess what I need to do is define a new list by extracting the first list from eigenvalues(M)...Not sure how to do that, however.
Another related question: some of these eigenvalues will be complex, so when I take the maximum of the list, will maxima ignore the complex numbers in the list and just look at the real-valued eigenvalues, or it will give me an error?
Firstly we input the matrix:
M : matrix([1,2],[2,3])$
Then we calculate its eigenvalues:
eigs : eigenvalues(M);
(%o56) [[2 - sqrt(5), sqrt(5) + 2], [1, 1]]
Finally, we extract the maximum eigenvalue:
lmax(first(eigs));
(%o59) sqrt(5) + 2
With regard to the maximum of a list of complex numbers, remember that the concept of maximum only belongs to the realm of real numbers. There is not a maximum of a set of complex numbers.
Here's how I would go about it. I'll assign the result of eigenvalues to two variables, so one is the first list and the other is the second. Note that I'm using parallel assignment for that, e.g. [a, b] : [foo, bar]; assigns foo to a and bar to b. Then I'll paste the elements in the two lists together, to keep each eigenvalue with its multiplicity. Finally I'll sort the eigenvalues by magnitude. I'll sort by decreasing magnitude, so the first element is the largest eigenvalue and its multiplicity.
(%i2) A : matrix ([1/7, 15/14, 15/7], [-13/7, 85/14, 71/7], [9/7, -27/7, -47/7]);
[ 1 15 15 ]
[ - -- -- ]
[ 7 14 7 ]
[ ]
[ 13 85 71 ]
(%o2) [ - -- -- -- ]
[ 7 14 7 ]
[ ]
[ 9 27 47 ]
[ - - -- - -- ]
[ 7 7 7 ]
(%i3) [vals, mults] : eigenvalues (A);
1
(%o3) [[-, - 2, 1], [1, 1, 1]]
2
(%i4) vals_mults : map (lambda ([a, b], [a, b]), vals, mults);
1
(%o4) [[-, 1], [- 2, 1], [1, 1]]
2
(%i5) sort (vals_mults, lambda ([a, b], abs(a[1]) > abs(b[1])));
1
(%o5) [[- 2, 1], [1, 1], [-, 1]]
2
(%i6) first (%);
(%o6) [- 2, 1]
The operation consists of two arrays X and idx of equal length where the values of idx can vary between 0 to (k-1) with the value of k given.
This is the general Python code to illustrate this.
import numpy as np
X = np.arange(6) # Just for a sample of elements
k = 3
idx = numpy.array([[0, 1, 2, 2, 0, 1]]).T # Can only contain values in [0..(k-1)]
np.array([X[np.where(idx==i)[0]] for i in range(k)])
Sample output:
array([[0, 4],
[1, 5],
[2, 3]])
Note that there is actually a reason for me to represent idx as a matrix and not as a vector. It was initialised to numpy.zeros((n,1)) as part of its computation, where n the size of X.
I tried implement this in Theano like so
import theano
import theano.tensor as T
X = T.vector('X')
idx = T.vector('idx')
k = T.scalar()
c = theano.scan(lambda i: X[T.where(T.eq(idx,i))], sequences=T.arange(k))
f = function([X,idx,k],c)
But I received this error at line where c is defined:
TypeError: Wrong number of inputs for Switch.make_node (got 1((<int8>,)), expected 3)
Is there a simple way to implement this in Theano?
Use nonzero() and correct the dimensions of idx.
This code solved the problem
import theano
import theano.tensor as T
X = T.vector('X')
idx = T.vector('idx')
k = T.scalar()
c, updates = theano.scan(lambda i: X[T.eq(idx,i).nonzero()], sequences=T.arange(k))
f = function([X,idx,k],c)
For the same example, through the use of Theano:
import numpy as np
X = np.arange(6)
k = 3
idx = np.array([[0, 1, 2, 2, 0, 1]]).T
f(X, idx.T[0], k).astype(int)
This gives the output as
array([[0, 4],
[1, 5],
[2, 3]])
If idx is defined as np.array([0, 1, 2, 2, 0, 1]), then f(X, idx, k) can be used instead.
I have two square matrices A and B
I must convert B to CSR Format and determine the product C
A * B_csr = C
I have found a lot of information online regarding CSR Matrix - Vector multiplication. The algorithm is:
for (k = 0; k < N; k = k + 1)
result[i] = 0;
for (i = 0; i < N; i = i + 1)
{
for (k = RowPtr[i]; k < RowPtr[i+1]; k = k + 1)
{
result[i] = result[i] + Val[k]*d[Col[k]];
}
}
However, I require Matrix - Matrix multiplication.
Further, it seems that most algorithms apply A_csr - vector multiplication where I require A * B_csr. My solution is to transpose the two matrices before converting then transpose the final product.
Can someone explain how to compute a Matrix - CSR Matrix product and/or a CSR Matrix - Matrix product?
Here is a simple solution in Python for the Dense Matrix X CSR Matrix. It should be self-explanatory.
def main():
# 4 x 4 csr matrix
# [1, 0, 0, 0],
# [2, 0, 3, 0],
# [0, 0, 0, 0],
# [0, 4, 0, 0],
csr_values = [1, 2, 3, 4]
col_idx = [0, 0, 2, 1]
row_ptr = [0, 1, 3, 3, 4]
csr_matrix = [
csr_values,
col_idx,
row_ptr
]
dense_matrix = [
[1, 3, 3, 4],
[1, 2, 3, 4],
[1, 4, 3, 4],
[1, 2, 3, 5],
]
res = [
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
]
# matrix order, assumes both matrices are square
n = len(dense_matrix)
# res = dense X csr
csr_row = 0 # Current row in CSR matrix
for i in range(n):
start, end = row_ptr[i], row_ptr[i + 1]
for j in range(start, end):
col, csr_value = col_idx[j], csr_values[j]
for k in range(n):
dense_value = dense_matrix[k][csr_row]
res[k][col] += csr_value * dense_value
csr_row += 1
print res
if __name__ == '__main__':
main()
CSR Matrix X Dense Matrix is really just a sequence of CSR Matrix X Vector product for each row of the dense matrix right? So it should be really easy to extend the code you show above to do this.
Moving forward, I suggest you don't code these routines yourself. If you are using C++ (based on the tag), then you could have a look at Boost ublas for example, or Eigen. The APIs may seem a bit cryptic at first but it's really worth it in the long term. First, you gain access to a lot more functionality, which you will probably require in the future. Second these implementations will be better optimised.
I've got a theano function which computes euclidean distances for 2 matrices—X (n vectors x k features) and Y (m vectors x k features). The result is an n x m matrix of pairwise distances of each vector (or row) in X from each vector (or row) in Y.
import theano
from theano import tensor as T
X, Y = T.dmatrices('X', 'Y')
X_squared_sum = T.sum(X ** 2, axis=1, keepdims=True)
Y_squared_sum = T.sum(Y.T ** 2, axis=0, keepdims=True)
squared_distances = X_squared_sum + Y_squared_sum - 2 * T.dot(X, Y.T)
f_distance = theano.function([X, Y], T.sqrt(squared_distances))
Let's say I change the above function to accept a single vector, an array of vectors, and the number of smallest distances. What I want is a theano function that will find the N smallest distances, similar to below:
import numpy as np
import theano
from theano import tensor as T
X = T.dvector('X')
Y = T.dmatrix('Y')
N = T.iscalar('N')
X_squared_sum = T.dot(X, X)
Y_squared_sum = T.sum(Y.T ** 2, axis=0)
squared_distances = X_squared_sum + Y_squared_sum - 2 * T.dot(X, Y.T)
dist_sorted = T.FIND_N_SMALLEST(T.sqrt(squared_distances), N)
n_closest = theano.function([X, Y, N], dist_sorted)
U = np.array([[1, 1, 1, 1]])
V = np.array([
[ 4, 4, 4, 4],
[ 2, 2, 2, 2],
[ 3, 3, 3, 3],
[ 1, 1, 1, 1]])
n_closest(U, V, 2) # [0.0, 2.0]
I'd like to avoid explicitly sorting all the distances, since the number that I want will generally be much much smaller than the total number of distances.
I'm using SymPy to do linear algebra. I want to perform an element-wise multiplication (Hadamard product) on two matricies.
For example,
sympy.MatrixSymbol('X', 4, 3) [operator/method] sympy.MatrixSymbol('W', 4, 3)
would give
[[X[0,0]*W[0,0], X[0,1]*W[0,1], ...],[X[1,0]*W[1,0], X[1,1]*W[1,1], ...]]
But it seems that there isn't a method for it. Is there any way to perform an element-wise multiplication with SymPy?
Yes there is a function in SymPy that can do element-wise multiplication (Hadamard product). As per their documentation of SymPy 0.7.6 the function is:
multiply_elementwise(b)
Returns the Hadamard product (elementwise product) of A and B.
Example:
>>> from sympy.matrices import Matrix
>>> A = Matrix([[0, 1, 2], [3, 4, 5]])
>>> B = Matrix([[1, 10, 100], [100, 10, 1]])
>>> A.multiply_elementwise(B)
Matrix([
[ 0, 10, 200],
[300, 40, 5]])
Update: For element-wise multiplication of MatrixSymbols use the following function:
HadamardProduct(A, B)
For Example:
>>> from sympy import HadamardProduct
>>> A = MatrixSymbol('A', m, n)
>>> B = MatrixSymbol('B', m, n)
>>>print(HadamardProduct(A,B))
A.*B