I want to multiply two matrices. A * B works just fine. But what I really want is A.t * B. But after transposing A, the result becomes Transpose[Matrix[Double]] instead of Matrix[Double]. As a result the operation is rejected by the compiler. However, mathematically, the transpose of a matrix is another matrix, and it should be perfectly ok to multiply that by another matrix. How is this properly done in breeze?
A.t.asInstanceOf[DenseMatrix[Double]] did the trick.
I had a similar problem when I was using a plain Matrix type in Breeze, for example something like this:
def buildMatrix(): Matrix[Double] = {
DenseMatrix((1.0, 2.0, 3.0), (4.0, 5.0, 6.0))
}
val m = buildMatrix()
val t = m.t
m * t
gives me the compiler error Error:(13, 69) could not find implicit value for parameter op: breeze.linalg.operators.OpMulMatrix.Impl2[breeze.linalg.Matrix[Double],breeze.linalg.Transpose[breeze.linalg.Matrix[Double]],That]
But if I make sure that the matrix I'm transposing is a DenseMatrix, like this:
val m = buildMatrix().toDenseMatrix
Then the * operator works fine.
Related
From the following
let v = OVector::<f64, U2>::from_column_slice(&[3_f64, 4_f64]);
let x = &v.transpose() * &v; // get the inner product, i.e. <v,v>
I expected x to be a f64 scalar, i.e. x = 25.0.
But actually, I can only obtain x as OMatrix::<f64, Cosnt<1>, Const<1>>.
The case can be even worse in matrix product operations. for example, the following code doesn't work since v^T v is not a scalar.
let m = OMatrix::<f64, U2, U2>::from_element(1.0);
let v = OVector::<f64, U2>::from_column_slice(&[3_f64, 4_f64]);
// not working
let y = &v.transpose() * &v * m; // types conflict
// working
let y = 25.0 * m; // expected to behave like this
What is the correct way to do this?
Usually, in maths, you would identify 1x1 matrices with scalars (because, for some definition of being equivalent, they are equivalent...). When doing this, the dot product of two vectors is exactly the dot product between two matrices, when we see vectors as matrix columns (which are also equivalent for some equivalence...).
However, here, it is not the case: Rust has to know what is the type of the data. So, I would suggest, since you are using matrices to start with, to use the actual matrix dot product, not the vector one. It's simply (v.transpose()*v).trace(). This is a more general dot product, but notice taking the trace will exactly "extract" the scalar from the 1x1 matrix.
Otherwise, this operation is already defined as the dot product (unsurprisingly): v.dot(v).
I am working in sympy with symbolic matrices.
Once made explicit I can not return to implicit representations.
I tried to work something out with the pair of .as_explicit() and MatrixExpr.from_index_summation(expr)
But the latter seems to expect an explicit sigma notation sum, not a sum of indexed elements.
As a minimal working example here is my approach on matrix multiplication:
A = MatrixSymbol('A',3,4)
B = MatrixSymbol('B',4,3)
Matrix_Notation = A * B
Expanded = (A * B).as_explicit()
FromSummation = MatrixExpr.from_index_summation(Expanded)
Here we can see, that FromSummation is still the same as Expanded
I suppose that the Expanded expression should be converted to sigma sums such that .from_index_summation can be expected to work. But how can this be done?
Sympy has BlockMatrix class, but it is not a regular Matrix,
eg you can not matrix multiply a BlockMatrix.
BlockMatrix is a convenient way to build a structured matrix, but I do not see a way to use it with unstructured matrices.
Is there a way to flatten a BlockMatrix, or another convenient way to build a regular Matrix from blocks, similar to numpy.blocks?
You can use the method as_explicit() to get a flat explicit matrix, like this:
from sympy import *
n = 3
X = Identity(n)
Y = Identity(n)
Z = Identity(n)
W = Identity(n)
R = BlockMatrix([[X,Y],[Z,W]])
print (R.as_explicit())
I'd like to numerically solve an equation involving a MatrixSymbol. Here's a basic example:
import sympy as sy
v = sy.MatrixSymbol('v', 2, 1)
equation = (v - sy.Matrix([17, 23])).as_explicit()
I'd like something like:
sy.nsolve(equation, v, sy.Matrix([0,0]))
But because nsolve does not accept MatrixSymbols, I've made a cludgy workaround that gives the correct output of Matrix([[17.0], [23.0]]):
vx, vy = sy.symbols('v_x v_y')
sy.nsolve(equation.subs(v, sy.Matrix([vx, vy])), [vx, vy], [0,0])
Essentially, I've converted a MatrixSymbol to a matrix of Symbols to make nsolve happy.
Is there a better way I should be doing this?
Edit: the workaround can be simplified to:
vseq = sy.symbols('a b') #names must be distinct
sy.nsolve(equation.subs(v, sy.Matrix(vseq)), vseq, [0,0])
But there ought to be a cleaner way to convert a MatrixSymbol to a sequence of Symbols, or a way to avoid needing to do so in the first place.
A cleaner way is to create a Matrix from symarray:
v = sy.Matrix(sy.symarray("v", (2,)))
equation = v - sy.Matrix([17, 23])
sy.nsolve(equation, v, [0, 0])
Here, symarray creates a (NumPy) array of symbols [v_0, v_1] which is then turned into a Matrix. One can also use sy.symarray("v", (2, 1)) so it's a double array, but since SymPy's Matrix constructor is cool with 1D inputs, this is not necessary.
I'm looking for a possibility to specify matrix quantities that depend on a variables. For scalars that works as follows, using undefined functions:
from sympy import *
x = Function('f')(t)
diff(x,t)
For Matrix Symbols like
x = MatrixSymbol('x',3,3)
i cannot find an equivalent. There is
i,j = Symbols('i j')
x = FunctionMatrix(6,1,Lambda((i,j),f))
but this is not what i need as you need to specify the contents of the matrix. The context is that i have equations
which should be derived in time and contain matrix valued elements.
I cannot deal with the elements of the matrices one by one.
Thanks!
I'm not sure about what you want, but I think you want to make a Matrix with differentiable elements. In that case, see if this works for you.
Create a matrix with function elements:
X = sym.FunctionMatrix(6,1,lambda i,j:sym.Function("x_%d%d" % (i,j))(t))
M = sym.Matrix(X)
M.diff(t)
This results in
Matrix([
[Derivative(x_00(t), t)],
[Derivative(x_10(t), t)],
[Derivative(x_20(t), t)],
[Derivative(x_30(t), t)],
[Derivative(x_40(t), t)],
[Derivative(x_50(t), t)]])
You may then replace stuff as you need.
Also, it may be preferrable if you populate the matrix with the expressions you need before differentiating. Leaving them as undefined functions may make it harder for you to simplify after substitution.