]>
gitweb.michael.orlitzky.com - sage.d.git/blob - mjo/eja/eja_utils.py
1 from sage
.functions
.other
import sqrt
2 from sage
.matrix
.constructor
import matrix
3 from sage
.modules
.free_module_element
import vector
6 return vector(m
.base_ring(), m
.list())
9 return matrix(v
.base_ring(), sqrt(v
.degree()), v
.list())
11 def gram_schmidt(v
, inner_product
=None):
13 Perform Gram-Schmidt on the list ``v`` which are assumed to be
14 vectors over the same base ring. Returns a list of orthonormalized
15 vectors over the smallest extention ring containing the necessary
20 sage: from mjo.eja.eja_utils import gram_schmidt
24 The usual inner-product and norm are default::
26 sage: v1 = vector(QQ,(1,2,3))
27 sage: v2 = vector(QQ,(1,-1,6))
28 sage: v3 = vector(QQ,(2,1,-1))
30 sage: u = gram_schmidt(v)
31 sage: all( u_i.inner_product(u_i).sqrt() == 1 for u_i in u )
33 sage: bool(u[0].inner_product(u[1]) == 0)
35 sage: bool(u[0].inner_product(u[2]) == 0)
37 sage: bool(u[1].inner_product(u[2]) == 0)
41 But if you supply a custom inner product, the result is
42 orthonormal with respect to that (and not the usual inner
45 sage: v1 = vector(QQ,(1,2,3))
46 sage: v2 = vector(QQ,(1,-1,6))
47 sage: v3 = vector(QQ,(2,1,-1))
49 sage: B = matrix(QQ, [ [6, 4, 2],
52 sage: ip = lambda x,y: (B*x).inner_product(y)
53 sage: norm = lambda x: ip(x,x)
54 sage: u = gram_schmidt(v,ip)
55 sage: all( norm(u_i) == 1 for u_i in u )
57 sage: ip(u[0],u[1]).is_zero()
59 sage: ip(u[0],u[2]).is_zero()
61 sage: ip(u[1],u[2]).is_zero()
64 This Gram-Schmidt routine can be used on matrices as well, so long
65 as an appropriate inner-product is provided::
67 sage: E11 = matrix(QQ, [ [1,0],
69 sage: E12 = matrix(QQ, [ [0,1],
71 sage: E22 = matrix(QQ, [ [0,0],
73 sage: I = matrix.identity(QQ,2)
74 sage: trace_ip = lambda X,Y: (X*Y).trace()
75 sage: gram_schmidt([E11,E12,I,E22], inner_product=trace_ip)
77 [1 0] [ 0 1/2*sqrt(2)] [0 0]
78 [0 0], [1/2*sqrt(2) 0], [0 1]
83 Ensure that zero vectors don't get in the way::
85 sage: v1 = vector(QQ,(1,2,3))
86 sage: v2 = vector(QQ,(1,-1,6))
87 sage: v3 = vector(QQ,(0,0,0))
89 sage: len(gram_schmidt(v)) == 2
93 if inner_product
is None:
94 inner_product
= lambda x
,y
: x
.inner_product(y
)
95 norm
= lambda x
: inner_product(x
,x
).sqrt()
98 return (inner_product(x
,y
)/inner_product(x
,x
))*x
100 v
= list(v
) # make a copy, don't clobber the input
102 # Drop all zero vectors before we start.
103 v
= [ v_i
for v_i
in v
if not v_i
.is_zero() ]
111 # First orthogonalize...
112 for i
in range(1,len(v
)):
113 # Earlier vectors can be made into zero so we have to ignore them.
114 v
[i
] -= sum( proj(v
[j
],v
[i
]) for j
in range(i
) if not v
[j
].is_zero() )
116 # And now drop all zero vectors again if they were "orthogonalized out."
117 v
= [ v_i
for v_i
in v
if not v_i
.is_zero() ]
119 # Just normalize. If the algebra is missing the roots, we can't add
120 # them here because then our subalgebra would have a bigger field
121 # than the superalgebra.
122 for i
in range(len(v
)):
123 v
[i
] = v
[i
] / norm(v
[i
])