Thanks for the tips. I got rid of the execs. Made it more general to
include non-othogonal generators and metric. Did some spot checks and seems
to be working. Unfortunately for cliff_elt in the FreeAlgebraQuotient there
is no cliff_elt.coefficients() or cliff_elt.coefficient(mon) nor
cliff_elt.generators() and for cliff_vect*cliff_vect which is scalar
ostensibly in the base ring but can't divide or coerce back into the base
ring. Had to write special functions. Also for n generators there are n
structure matrices which are (2^n) x (2^n) to define the quotient, and I
don't know the practical limits on the number of generators
#Clifford Algebra construction with FreeAlgebraQuotient both orthogonal or
non-orthogonal
def GenMul(free_gen1,free_gen2):
ii = F.gens().index(free_gen1)
jj = F.gens().index(free_gen2)
if free_gen1==free_gen2:
return Metric[ii,jj]
else:
return MGGG[ii,jj]
def GenList(bit_str,Struct):
gen_list = []
for jj in range(nn):
if bit_str[jj]=='0':
gen_list.append(Struct(1))
else:
gen_list.append(Struct.gen(nn-jj-1))
return gen_list[::-1]
def MonProduct(mon_list):
mon_prod = mon_list[0]
for jj in range(1,len(mon_list)):
mon_prod = mon_prod*mon_list[jj]
return mon_prod
def MonsMats():
mons_str = []
mons_list = []
mons = []
for ii in range(2**nn):
bit_str = Integer(ii+nn^2).binary()[1:nn+1] # reversed '1011'
corresponds to g0*g1*g3 etc
mons_list.append(GenList(bit_str,PRGA))
mons.append(MonProduct(GenList(bit_str,F)))
mons_str = [str(mons[kk]) for kk in range(len(mons))]
mons_str_sorted = sorted(sorted(mons_str),key=len)
# sort mons lexicographically then by lowest degree first
mons_list = [mons_list[[mons_str.index(mons_str_sorted[kk]) for kk in
range(len(mons_str))][ll]] for ll in range(len(mons_str))]
mons = [mons[[mons_str.index(mons_str_sorted[kk]) for kk in
range(len(mons_str))][ll]] for ll in range(len(mons_str))]
mats = []
for g in PRGA.gens():
xgen = []
for m in mons_list:
m2 = m[:] # make copy by value not ref
res1 = []
for ii in range(len(m)-1, PRGA.gens().index(g)-1,-1):
if g < m[ii]:
res1.append((GenMul(m2[ii],g) +
g*m2[ii])*MonProduct(m2[0:ii]+m2[ii+1:len(m2)]))
m2[ii] = -m2[ii]
elif m[ii]==1 and PRGA.gens().index(g) != ii:
continue
elif m[ii]==1 and PRGA.gens().index(g) == ii:
m2[ii] = g
break
else:
m2[ii] = GenMul(g,g)
break
xgen.append(sum(res1) + MonProduct(m2))
# nn (2^nn x 2^nn) structure matrices ? practical limit on number
nn of generators ?
mats.append(matrix([[mxg.coefficient(m) for m in mons] for mxg in
xgen]))
gen_names = tuple(str(g) for g in PRGA.gens())
return [mons, mats, gen_names]
def cliff_coef(cliff_elt):
Struct=cliff_elt.parent()
return tuple(Struct.free_algebra()(str(cliff_elt)).coefficient(mon) for
mon in Struct.monomial_basis())
def cliff_inner(cliff_vect):
Struct=cliff_vect.parent()
return
Struct.free_algebra()(str(cliff_vect*cliff_vect)).coefficient(Struct.monoid()(1))
# random example
BaseRing = QQ
signat = diagonal_matrix(BaseRing,[1,-1,-1,-1])
nn = signat.nrows()
rank = 0
while rank<nn:
Metric = random_matrix(BaseRing,nn)
rank = Metric.rank()
Metric = Metric.transpose()*signat*Metric # somewhat random
non-orthogonal symmetric full rank Metric with signature defined above
PRGA = FreeAlgebra(BaseRing,nn,'g')
F = PRGA.monoid()
F.inject_variables()
MG = matrix(PRGA.gens())
MGG = MG.transpose()*MG
MGGG = 2*Metric - MGG.transpose() # global used in function
GenMul(x,y) as is global Metric
mons_mats = MonsMats()
ST = FreeAlgebraQuotient(PRGA,mons_mats[0],mons_mats[1],names=mons_mats[2])
ST.inject_variables()
# examples
cliff_elt = g3*g2*g1*g0
[ST.free_algebra()(str(cliff_elt)).coefficient(mon) for mon in
ST.monomial_basis()] # st_elt.coefficients() results in error since
it has no such attribute
# or
tuple(ST.free_algebra()(str(cliff_elt)).coefficient(mon) for mon in
ST.monomial_basis()) # is a possiblity
print(cliff_elt);print(cliff_coef(cliff_elt))
cliff_vect = 5*g0+7*g1-2*g2+6*g3/7
# to get the inner product back in the base ring, can't divide say
g3/(g3*g3) even though g3*g3 scalar ostensibly in base field but not...
ST.free_algebra()(str(cliff_vect*cliff_vect)).coefficient(ST.monoid()(1))
print(cliff_vect);print(cliff_coef(cliff_vect));print(cliff_inner(cliff_vect))
On Tue, Jul 29, 2014 at 12:17 AM, Nils Bruin <[email protected]> wrote:
> On Monday, July 28, 2014 7:24:47 PM UTC-7, Stephen Kauffman wrote:
>>
>>
>> exec preparse('ST.<' + gen_str + '>=FreeAlgebraQuotient(PRGA,
>> mons_mats[0],mons_mats[1])')
>>
>
> Congratulations to get all of this figured out! It's nice to see code of
> this generality.
>
> Please use
>
> gen_names=tuple(str(g) for g in PRGA.gens())
> ST=FreeAlgebraQuotient(PRGA,mons_mats[0],mons_mats[1],names=gen_names)
>
> instead, and perhaps
>
> ST.inject_variables()
>
> if you want the generators bound to corresponding names in the current
> global scope.
>
> You should really avoid "exec" whenever you can. For one thing, it makes
> it really difficult for the Python compiler to do a decent job.
>
> --
> You received this message because you are subscribed to the Google Groups
> "sage-support" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/sage-support.
> For more options, visit https://groups.google.com/d/optout.
>
--
You received this message because you are subscribed to the Google Groups
"sage-support" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-support.
For more options, visit https://groups.google.com/d/optout.