Hi Michael,

I do not know about preimplemented algorithms outside Sage itself, but it 
would not be so difficult to define this map directly. For example, as a 
map to the free algebra:

sage: T.<u,v,w> = FreeAlgebra(QQ)
sage: R.<x,y,z> = PolynomialRing(QQ)
sage: def _polarize(f):
....:     M = T.indices()
....:     D = {}
....:     for e, c in zip(f.exponents(), f.coefficients()):
....:         c2 = c / multinomial(e)
....:         for p in Permutations(M(list(enumerate(e))).to_list()):
....:             D[M.prod(p)] = c2
....:     return T._from_dict(D)
sage: from sage.categories.morphism import SetMorphism
sage: polarize = SetMorphism(Hom(R, T, Modules(R.base_ring())), _polarize)
sage: polarize(x^2*y + x*y*z)
1/3*u^2*v + 1/3*u*v*u + 1/6*u*v*w + 1/6*u*w*v + 1/3*v*u^2 + 1/6*v*u*w + 1/6*
v*w*u + 1/6*w*u*v + 1/6*w*v*u

Now this is a one-sided inverse for symmetrization:

sage: symmetrize = T.module_morphism(on_basis=lambda a: R.prod(R.gen(ai)^ni 
for ai, ni in a._element_list),
....:                                codomain=R)
sage: f = R.random_element(6, 15)
sage: symmetrize(polarize(f)) == f
True

The main problem with this is the combinatorial complexity, as the output 
quickly becomes huge for larger input. So it might be better if you can 
avoid computing this representation explicitly in your use case. After all, 
all this does is to divide the coefficients by some multinomial 
coefficient. Nevertheless, I still think this functionality would be useful 
for small cases and nice to have in Sage.

Alternatively, if you are more interested in viewing this as a multilinear 
form, then TensorFreeModule may be more suitable. This representation keeps 
track of symmetries in order to store coefficients without redundancy. Here 
is a quick example, but there may be room for improvement:

def polarize_form(f):
    n = f.parent().ngens()
    V = FiniteRankFreeModule(f.parent().base_ring(), n, name='V')
    B = V.basis('x')
    from sage.tensor.modules.tensor_free_module import TensorFreeModule
    T = TensorFreeModule(V, (0, n))
    t = T([], name='t', sym=range(n))
    for e, c in zip(f.exponents(), f.coefficients()):
        idx = [j for j, ej in e.sparse_iter() for _ in range(ej)]
        t.set_comp(B)[idx] = c / multinomial(e)
    return t

sage: t = polarize_form(x^2*y + x*y*z)
sage: t.symmetries()
symmetry: (0, 1, 2); no antisymmetry
sage: t.display()
t = 1/3 x_0*x_0*x_1 + 1/3 x_0*x_1*x_0 + 1/6 x_0*x_1*x_2 + 1/6 x_0*x_2*x_1 + 
1/3 x_1*x_0*x_0 + 1/6 x_1*x_0*x_2 + 1/6 x_1*x_2*x_0 + 1/6 x_2*x_0*x_1 + 1/6 
x_2*x_1*x_0
sage: V = t.base_module()
sage: t(V([0,0,1]), V([1,7,3]), V([1,0,0]))
7/6

Best,
Markus

-- 
You received this message because you are subscribed to the Google Groups 
"sage-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-devel+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sage-devel/36efbf3f-9672-48bb-a925-33963f83ac6a%40googlegroups.com.

Reply via email to