maxima: How to transform a symbolic matrix by specific variables - matrix

In maxima I have calculated a complicated 2x2 matrix, let's call it "HUGE" and it has 8 variables in it:
a, b, c, d, tr11, tr12, tr21, tr22
This is not correct syntax, but just to illustrate:
Given
HUGE(a,b,c,d,tr11,tr12,tr21,tr22)=matrix([0,0],[0,0])
I want to factorize/transform it into
HUGE_NEW(a,b,c,d)=matrix([tr11,tr21],[tr12,tr22])
By writing things like HUGE_NEW(a,b,c,d) I mean a new matrix that contains variables a,b,c,d only.
In other words I want to say something like
solve (HUGE - matrix([tr11,tr21],[tr12,tr22]) = matrix([0,0],[0,0]), [a, b, c, d], [tr11, tr12, tr21, tr22])
How can I go about it? My matrix is really complicated, so doing it with pen and paper is not an option.
In case someone asks for the actual value of my HUGE-matrix to try it out:
HUGE: matrix([−(sqrt(d^2−2*a*d+4*b*c+a^2)*((b*d+a*b)*tr12*tr22+(−d^2−a*d)*tr12*tr21+(−b*d−a*b)*tr11*tr12+(d^2+a*d)*tr11^2)+(b*d^2+2*b^2*c+a^2*b)*tr12*tr22+((−2*b*c−a^2)*d−d^3)*tr12*tr21+(b*d^2+2*b^2*c+a^2*b)*tr11*tr12+((−2*b*c−a^2)*d−d^3)*tr11^2)/(2*a*d−2*b*c),−(sqrt(d^2−2*a*d+4*b*c+a^2)*((b*d+a*b)*tr22^2+(−d^2−a*d)*tr21*tr22+((−b*d−a*b)*tr12+(d^2+a*d)*tr11)*tr21)+(b*d^2+2*b^2*c+a^2*b)*tr22^2+((−2*b*c−a^2)*d−d^3)*tr21*tr22+((b*d^2+2*b^2*c+a^2*b)*tr12+((−2*b*c−a^2)*d−d^3)*tr11)*tr21)/(2*a*d−2*b*c)],[(sqrt(d^2−2*a*d+4*b*c+a^2)*((a*d+a^2)*tr12*tr22+(−c*d−a*c)*tr12*tr21+(−a*d−a^2)*tr11*tr12+(c*d+a*c)*tr11^2)+(a*d^2+2*a*b*c+a^3)*tr12*tr22+(−c*d^2−2*b*c^2−a^2*c)*tr12*tr21+(a*d^2+2*a*b*c+a^3)*tr11*tr12+(−c*d^2−2*b*c^2−a^2*c)*tr11^2)/(2*a*d−2*b*c),(sqrt(d^2−2*a*d+4*b*c+a^2)*((a*d+a^2)*tr22^2+(−c*d−a*c)*tr21*tr22+((−a*d−a^2)*tr12+(c*d+a*c)*tr11)*tr21)+(a*d^2+2*a*b*c+a^3)*tr22^2+(−c*d^2−2*b*c^2−a^2*c)*tr21*tr22+((a*d^2+2*a*b*c+a^3)*tr12+(−c*d^2−2*b*c^2−a^2*c)*tr11)*tr21)/(2*a*d−2*b*c)])
Edit:
When I do this:
solve(HUGE = matrix([0,0],[0,0]),[tr11,tr12,tr21,tr11]);
maxima returns:
[]
I also tried:
solve([
−(sqrt(d^2−2*a*d+4*b*c+a^2)*((b*d+a*b)*tr12*tr22+(−d^2−a*d)*tr12*tr21+(−b*d−a*b)*tr11*tr12+(d^2+a*d)*tr11^2)+(b*d^2+2*b^2*c+a^2*b)*tr12*tr22+((−2*b*c−a^2)*d−d^3)*tr12*tr21+(b*d^2+2*b^2*c+a^2*b)*tr11*tr12+((−2*b*c−a^2)*d−d^3)*tr11^2+2*a^2*d−2*a*b*c)/(2*a*d−2*b*c)=0,
−(sqrt(d^2−2*a*d+4*b*c+a^2)*((b*d+a*b)*tr22^2+(−d^2−a*d)*tr21*tr22+((−b*d−a*b)*tr12+(d^2+a*d)*tr11)*tr21)+(b*d^2+2*b^2*c+a^2*b)*tr22^2+((−2*b*c−a^2)*d−d^3)*tr21*tr22+((b*d^2+2*b^2*c+a^2*b)*tr12+((−2*b*c−a^2)*d−d^3)*tr11)*tr21+2*a*c*d−2*b*c^2)/(2*a*d−2*b*c)=0,
(sqrt(d^2−2*a*d+4*b*c+a^2)*((a*d+a^2)*tr12*tr22+(−c*d−a*c)*tr12*tr21+(−a*d−a^2)*tr11*tr12+(c*d+a*c)*tr11^2)+(a*d^2+2*a*b*c+a^3)*tr12*tr22+(−c*d^2−2*b*c^2−a^2*c)*tr12*tr21+(a*d^2+2*a*b*c+a^3)*tr11*tr12+(−c*d^2−2*b*c^2−a^2*c)*tr11^2−2*a*b*d+2*b^2*c)/(2*a*d−2*b*c)=0,
(sqrt(d^2−2*a*d+4*b*c+a^2)*((a*d+a^2)*tr22^2+(−c*d−a*c)*tr21*tr22+((−a*d−a^2)*tr12+(c*d+a*c)*tr11)*tr21)+(a*d^2+2*a*b*c+a^3)*tr22^2+(−c*d^2−2*b*c^2−a^2*c)*tr21*tr22+((a*d^2+2*a*b*c+a^3)*tr12+(−c*d^2−2*b*c^2−a^2*c)*tr11)*tr21−2*a*d^2+2*b*c*d)/(2*a*d−2*b*c)=0
],[tr11,tr12,tr21,tr22]);
which results in an error:
Polynomial quotient is not exact
-- an error. To debug this try: debugmode(true);

I see your equations have sqrt in them. Try the to_poly_solve package for that. i.e. load(to_poly_solve); and then to_poly_solve([HUGE[1,1] = 0, HUGE[1,2] = 0, HUGE[2,1] = 0, HUGE[2,2] = 0], [tr11, tr12, tr21, tr22]);
When I try that, I get several messy expressions as a result. I didn't check to see if they are correct solutions. Good luck, have fun, let us know how it goes.

Related

sympy nsolve with MatrixSymbol

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.

Comparing sets of roots for polynom (SAGEMATH)

I am missing something about how to compare list of roots.
During a small algorithm I need to know wether a matrix has or not complex eigenvalues. I did the following
A=matrix(QQ,[[1,2,1],[6,-1,0],[-1,-2,-1]])
a=(B.charpoly()).roots(ring= QQ, multiplicities=False)
b=(B.charpoly()).roots(ring= QQbar, multiplicities=False)
then a is the list [-4,0,3] and b is the list [3,0,-4].
I don't get the following :
set(a)==set(b)
return false while
set([-4,0,3])==set([3,0,-4])
return true.
Any help, either on the first pb (knowing that a QQ matrix has complex eigenvalues) or on the second would be greatly appreciated.
Cheers.
L.

How is `(d*a)mod(b)=1` written in Ruby?

How should I write this:
(d*a)mod(b)=1
in order to make it work properly in Ruby? I tried it on Wolfram, but their solution:
(da(b, d))/(dd) = -a/d
doesn't help me. I know a and b. I need to solve (d*a)mod(b)=1 for d in the form d=....
It's not clear what you're asking, and, depending on what you mean, a solution may be impossible.
First off, (da(b, d))/(dd) = -a/d, is not a solution to that equation; rather, it's a misinterpretation of the notation used for partial derivatives. What Wolfram Alpha actually gave you was:
, which is entirely unrelated.
Secondly, if you're trying to solve (d*a)mod(b)=1 for d, you may be out of luck. For any value of a and b, where a and b have a common prime factor, there are an infinite number of values of d that satisfy the equation. If a and b are coprime, you can use the formula given in LutzL's answer.
Additionally, if you're looking to perform symbolic manipulation of equations, Ruby is likely not the proper tool. Consider using a CAS, like Python's SymPy or Wolfram Mathematica.
Finally, if you're just trying to compute (d*a)mod(b), the modulo operator in Ruby is %, so you'd write (d*a)%(b).
You are looking for the modular inverse of a modulo b.
For any two numbers a,b the extended euclidean algorithm
g,u,v = xgcd(a, b)
gives coefficients u,v such that
u*a+v*b = g
and g is the greatest common divisor. You need a,b co-prime, preferably by ensuring that b is a prime number, to get g=1 and then you can set d=u.
xgcd(a,b)
if b = 0
return (a,1,0)
q,r = a divmod b
// a = q*b + r
g,u,v = xgcd(b, r)
// g = u*b + v*r = u*b + v*(a-q*b) = v*a+(u-q*v)*b
return g,v,u - q*v

How to make this loop faster in matlab

I have to multiply arrays A and B element by element and calculate the sum of the first dimension, then returns the result in C. A is a N-by-M-by-L matrix. B is a N-by-1-by-L matrix. N and M is lower than 30, but L is very large. My code is:
C=zeros(size(B));
parfor i=1:size(A,2)
C(i,1,:) = sum(bsxfun(#times, A(:,i,:), B(:,1,:)), 1);
end
The problem is the code is slow, anyone can help to make the code faster? Thank you very much.
How about something along the lines of this:
C = permute(sum(A.*repmat(B,1,M)),[2,1,3]);
This speeds computation on my PC up by a factor of ~4. Interestingly enough, you can actually speed up the computation by a factor of 2 (at least on my PC) simply by changing the parfor loop to a for loop.
If I understand correctly, just do this:
C = squeeze(sum(bsxfun(#times, A, B)));
This gives C with size M x L.
Taking the comments from Luis Mendo, I propose to use this command:
C=reshape(sum(bsxfun(#times, A, B), 1), size(B))
I think this is the fastest.

Working Matrix Square root

I'm trying to take the square root of a matrix. That is find the matrix B so B*B=A. None of the methods I've found around gives a working result.
First I found this formula on Wikipedia:
Set Y_0 = A and Z_0 = I then the iteration:
Y_{k+1} = .5*(Y_k + Z_k^{-1}),
Z_{k+1} = .5*(Z_k + Y_k^{-1}).
Then Y should converge to B.
However implementing the algorithm in python (using numpy for inverse matrices), gave me rubbish results:
>>> def denbev(Y,Z,n):
if n == 0: return Y,Z
return denbev(.5*(Y+Z**-1), .5*(Z+Y**-1), n-1)
>>> denbev(matrix('1,2;3,4'), matrix('1,0;0,1'), 3)[0]**2
matrix([[ 1.31969074, 1.85986159],
[ 2.78979239, 4.10948313]])
>>> denbev(matrix('1,2;3,4'), matrix('1,0;0,1'), 100)[0]**2
matrix([[ 1.44409972, 1.79685675],
[ 2.69528512, 4.13938485]])
As you can see, iterating 100 times, gives worse results than iterating three times, and none of the results get within a 40% error margin.
Then I tried the scipy sqrtm method, but that was even worse:
>>> scipy.linalg.sqrtm(matrix('1,2;3,4'))**2
array([[ 0.09090909+0.51425948j, 0.60606061-0.34283965j],
[ 1.36363636-0.77138922j, 3.09090909+0.51425948j]])
>>> scipy.linalg.sqrtm(matrix('1,2;3,4')**2)
array([[ 1.56669890+0.j, 1.74077656+0.j],
[ 2.61116484+0.j, 4.17786374+0.j]])
I don't know a lot about matrix square rooting, but I figure there must be algorithms that perform better than the above?
(1) the square root of the matrix [1,2;3,4] should give something complex, as the eigenvalues of that matrix are negative. SO your solution can't be correct to begin with.
(2) linalg.sqrtm returns an array, NOT a matrix. Hence, using * to multiply them is not a good idea. In your case, the solutions is thus correct, but you're not seeing it.
edit try the following, you'll see it's correct:
asmatrix(scipy.linalg.sqrtm(matrix('1,2;3,4')))**2
Your matrix [1 2; 3 4] isn't positive so there is no solution to the problem in the domain of real matrices.
What is the purpose of the matrix square root that you're doing? I suspect a practical application the matrix really could be symmetric positive definite (e.g. covariance) so you shouldn't encounter complex numbers.
In that case you can compute a cholesky decomposition, like a scaled LU factorization, see here: http://en.wikipedia.org/wiki/Cholesky_decomposition
Another practical example is if your matrices are rotations, then you can first decompose with matrix log and just divide by 2 in the log space, then go back to rotation with matrix exponent... in any event it sounds strange that you ask for a 'generic matrix square root', you probably want to understand the specific application in more depth.

Resources