In a desperate attempt to switch from Matlab to python, I am encountering the following problem:
In Matlab, I am able to define a matrix like:
N = [1 0 0 0 -1 -1 -1 0 0 0;% A
0 1 0 0 1 0 0 -1 -1 0;% B
0 0 0 0 0 1 0 1 0 -1;% C
0 0 0 0 0 0 1 0 0 -1;% D
0 0 0 -1 0 0 0 0 0 1;% E
0 0 -1 0 0 0 0 0 1 1]% F
The rational basis nullspace (kernel) can then be calculated by:
K_nur= null(N,'r')
And the orthonormal basis like:
K_nuo= null(N)
This outputs the following:
N =
1 0 0 0 -1 -1 -1 0 0 0
0 1 0 0 1 0 0 -1 -1 0
0 0 0 0 0 1 0 1 0 -1
0 0 0 0 0 0 1 0 0 -1
0 0 0 -1 0 0 0 0 0 1
0 0 -1 0 0 0 0 0 1 1
K_nur =
1 -1 0 2
-1 1 1 0
0 0 1 1
0 0 0 1
1 0 0 0
0 -1 0 1
0 0 0 1
0 1 0 0
0 0 1 0
0 0 0 1
K_nuo =
0.5933 0.1332 0.3070 -0.3218
-0.0930 0.0433 0.2029 0.7120
0.1415 0.0084 0.5719 0.2220
0.3589 0.1682 -0.0620 0.1682
-0.1628 0.4518 0.3389 -0.4617
0.3972 -0.4867 0.0301 -0.0283
0.3589 0.1682 -0.0620 0.1682
-0.0383 0.6549 -0.0921 0.1965
-0.2174 -0.1598 0.6339 0.0538
0.3589 0.1682 -0.0620 0.1682
I have been trying to replicate this in Python SAGE, but so far, I have had no success. My code looks like this:
st1= matrix([
[ 1, 0, 0, 0,-1,-1,-1, 0, 0, 0],
[ 0, 1, 0, 0, 1, 0, 0,-1,-1, 0],
[ 0, 0, 0, 0, 0, 1, 0, 1, 0,-1],
[ 0, 0, 0, 0, 0, 0, 1, 0, 0,-1],
[ 0, 0, 0,-1, 0, 0, 0, 0, 0, 1],
[ 0, 0,-1, 0, 0, 0, 0, 0, 1, 1]])
print st1
null2_or= transpose(st1).kernel()
null2_ra= transpose(st1).kernel().basis()
print "nullr2_or"
print null2_or
print "nullr2_ra"
print null2_ra
Note: The transpose was introduced after reading through some tutorials on this and has to do with the nature of SAGE automatically computing the kernel from the left (which in this case yields no result at all).
The problem with this now is: It DOES print me something… But not the right thing.
The output is as follows:
sage: load stochiometric.py
[ 1 0 0 0 -1 -1 -1 0 0 0]
[ 0 1 0 0 1 0 0 -1 -1 0]
[ 0 0 0 0 0 1 0 1 0 -1]
[ 0 0 0 0 0 0 1 0 0 -1]
[ 0 0 0 -1 0 0 0 0 0 1]
[ 0 0 -1 0 0 0 0 0 1 1]
nullr2_or
Free module of degree 10 and rank 4 over Integer Ring
Echelon basis matrix:
[ 1 0 0 1 0 0 1 1 -1 1]
[ 0 1 0 1 0 -1 1 2 -1 1]
[ 0 0 1 -1 0 1 -1 -2 2 -1]
[ 0 0 0 0 1 -1 0 1 0 0]
nullr2_ra
[
(1, 0, 0, 1, 0, 0, 1, 1, -1, 1),
(0, 1, 0, 1, 0, -1, 1, 2, -1, 1),
(0, 0, 1, -1, 0, 1, -1, -2, 2, -1),
(0, 0, 0, 0, 1, -1, 0, 1, 0, 0)
]
Upon closer inspection, you can see that the resulting kernel matrix (nullspace) looks similar, but is not the same.
Does anyone know what I need to do to get the same result as in Matlab and, if possible, how to obtain the orthonormal result (in Matlab called K_nuo).
I have tried to look through the tutorials, documentation etc., but so far, no luck.
Something like this should work:
The
gram_schmidtmethod gives a pair of matrices. TypeM.gram_schmidt?to see the documentation.The matrix
st1has integer entries, so Sage treats it as a matrix of integers, and tries to do as much as possible with integer arithmetic, and failing that, rational arithmetic. Because of this, Gram-Schmidt orthonormalization will fail, since it involves taking square roots. This is why the methodchange_ring(RDF)is there:RDFstands for Real Double Field. You could instead just change one entry ofst1from1to1.0, and then it will treatst1as a matrix over RDF from the start and you won’t need to do thischange_ringanywhere.