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
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 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 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
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.
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.