Path: blob/master/sage/tensor/differential_form_element.py
4045 views
r"""1Elements of the algebra of differential forms23AUTHORS:45- Joris Vankerschaver (2010-07-25)67"""89#*****************************************************************************10# Copyright (C) 2010 Joris Vankerschaver <[email protected]>11#12# Distributed under the terms of the GNU General Public License (GPL)13#14# This code is distributed in the hope that it will be useful,15# but WITHOUT ANY WARRANTY; without even the implied warranty of16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU17# General Public License for more details.18#19# The full text of the GPL is available at:20#21# http://www.gnu.org/licenses/22#*****************************************************************************232425from sage.symbolic.ring import SR26from sage.rings.ring_element import RingElement27from sage.algebras.algebra_element import AlgebraElement28from sage.rings.integer import Integer29from sage.combinat.permutation import Permutation303132def sort_subscript(subscript):33"""34A subscript is a range of integers. This function sorts a subscript35in the sense of arranging it in ascending order. The return values36are the sign of the subscript and the sorted subscript, where the37sign is defined as follows:3839#. sign == 0 if two or more entries in the subscript were equal.40#. sign == +1, -1 if a positive (resp. negative) permutation was used to sort the subscript.414243INPUT:4445- ``subscript`` -- a subscript, i.e. a range of not necessarily46distinct integers474849OUTPUT:5051- Sign of the permutation used to arrange the subscript, where 052means that the original subscript had two or more entries that53were the same5455- Sorted subscript.565758EXAMPLES::5960sage: from sage.tensor.differential_form_element import sort_subscript61sage: sort_subscript((1, 3, 2))62(-1, (1, 2, 3))63sage: sort_subscript((1, 3))64(1, (1, 3))65sage: sort_subscript((4, 2, 7, 9, 8))66(1, (2, 4, 7, 8, 9))6768"""69if len(subscript) == 0:70return 1, ()7172sub_list = list(subscript)73sub_list.sort()74offsets = [subscript.index(x)+1 for x in sub_list]7576# Check that offsets is a true permutation of 1..n77n = len(offsets)78if sum(offsets) != n*(n+1)/2:79sign = 080else:81sign = Permutation(offsets).signature()8283return sign, tuple(sub_list)84858687class DifferentialFormFormatter:88r"""89This class contains all the functionality to print a differential form in a90graphically pleasing way. This class is called by the ``_latex_`` and91``_repr_`` methods of the DifferentialForm class.9293In a nutshell (see the documentation of ``DifferentialForm`` for more94details), differential forms are represented internally as a dictionary,95where the keys are tuples representing the non-zero components of the96form and the values are the component functions. The methods of this97class create string and latex representations out of the specification98of a subscript and a component function.99100101EXAMPLES::102103sage: from sage.tensor.differential_form_element import DifferentialFormFormatter104sage: x, y, z = var('x, y, z')105sage: U = CoordinatePatch((x, y, z))106sage: D = DifferentialFormFormatter(U)107sage: D.repr((0, 2), sin(x*y))108'sin(x*y)*dx/\\dz'109sage: D.latex((0, 2), sin(x*y))110'\\sin\\left(x y\\right) d x \\wedge d z'111sage: D.latex((1, 2), exp(z))112'e^{z} d y \\wedge d z'113114"""115def __init__(self, space):116r"""117Construct a differential form formatter. See118``DifferentialFormFormatter`` for more information.119120INPUT:121122- space -- CoordinatePatch where the differential forms live.123124EXAMPLES::125126sage: from sage.tensor.differential_form_element import DifferentialFormFormatter127sage: x, y, z = var('x, y, z')128sage: U = CoordinatePatch((x, y, z))129sage: D = DifferentialFormFormatter(U)130sage: D.repr((0, 2), sin(x*y))131'sin(x*y)*dx/\\dz'132133"""134self._space = space135136137def repr(self, comp, fun):138r"""139String representation of a primitive differential form, i.e. a function140times a wedge product of d's of the coordinate functions.141142INPUT:143144- ``comp`` -- a subscript of a differential form.145146- ``fun`` -- the component function of this form.147148149EXAMPLES::150151sage: from sage.tensor.differential_form_element import DifferentialFormFormatter152sage: x, y, z = var('x, y, z')153sage: U = CoordinatePatch((x, y, z))154sage: D = DifferentialFormFormatter(U)155sage: D.repr((0, 1), z^3)156'z^3*dx/\\dy'157158"""159160str = "/\\".join( \161[('d%s' % self._space.coordinate(c).__repr__()) for c in comp])162163if fun == 1 and len(comp) > 0:164# We have a non-trivial form whose component function is 1,165# so we just return the formatted form part and ignore the 1.166return str167else:168funstr = fun._repr_()169170if not self._is_atomic(funstr):171funstr = '(' + funstr + ')'172173if len(str) > 0:174return funstr + "*" + str175else:176return funstr177178179def latex(self, comp, fun):180r"""181Latex representation of a primitive differential form, i.e. a function182times a wedge product of d's of the coordinate functions.183184INPUT:185186- ``comp`` -- a subscript of a differential form.187188- ``fun`` -- the component function of this form.189190EXAMPLES::191192sage: from sage.tensor.differential_form_element import DifferentialFormFormatter193sage: x, y, z = var('x, y, z')194sage: U = CoordinatePatch((x, y, z))195sage: D = DifferentialFormFormatter(U)196sage: D.latex((0, 1), z^3)197'z^{3} d x \\wedge d y'198sage: D.latex((), 1)199'1'200sage: D.latex((), z^3)201'z^{3}'202sage: D.latex((0,), 1)203'd x'204"""205206from sage.misc.latex import latex207208s = " \\wedge ".join( \209[('d %s' % latex(self._space.coordinate(c))) for c in comp])210211# Make sure this is a string and not a LatexExpr212s = str(s)213214# Add coefficient except if it's 1215if fun == 1:216if s:217return s218else:219return "1"220221funstr = fun._latex_()222if not self._is_atomic(funstr):223funstr = '(' + funstr + ')'224225if s:226s = " " + s227return funstr + s228229230def _is_atomic(self, str):231r"""232Helper function to check whether a given string expression233is atomic.234235EXAMPLES::236237sage: x, y, z = var('x, y, z')238sage: U = CoordinatePatch((x, y, z))239sage: from sage.tensor.differential_form_element import DifferentialFormFormatter240sage: D = DifferentialFormFormatter(U)241sage: D._is_atomic('a + b')242False243sage: D._is_atomic('(a + b)')244True245"""246level = 0247for n, c in enumerate(str):248if c == '(':249level += 1250elif c == ')':251level -= 1252253if c == '+' or c == '-':254if level == 0 and n > 0:255return False256return True257258259260class DifferentialForm(AlgebraElement):261r"""262Differential form class.263264EXAMPLES:265266In order to instantiate differential forms of various degree, we begin267by specifying the CoordinatePatch on which they live, as well as their268parent DifferentialForms algebra.269270::271272sage: x, y, z = var('x, y, z')273sage: U = CoordinatePatch((x, y, z))274sage: F = DifferentialForms(U)275sage: form1 = DifferentialForm(F, 0, sin(x*y)); form1276sin(x*y)277278In the previous example, we created a zero-form from a given function.279To create forms of higher degree, we can use the subscript operator280access the various components::281282sage: form2 = DifferentialForm(F, 1); form22830284sage: form2[0] = 1285sage: form2[1] = exp(cos(x))286sage: form2[2] = 1/ln(y)287sage: form22881/log(y)*dz + dx + e^cos(x)*dy289290We may calculate the exterior derivative of a form, and observe that291applying the exterior derivative twice always yields zero::292293sage: dform = form1.diff(); dform294y*cos(x*y)*dx + x*cos(x*y)*dy295sage: dform.diff()2960297298As can be seen from the previous example, the exterior derivative299increases the degree of a form by one::300301sage: form2.degree()3021303sage: form2.diff().degree()3042305306The ``d`` function provides a convenient shorthand for applying the307diff member function. Since d appears in other areas of mathematics308as well, this function is not imported in the global namespace309automatically::310311sage: from sage.tensor.differential_form_element import d312sage: form23131/log(y)*dz + dx + e^cos(x)*dy314sage: d(form2)315-(1/y)/log(y)^2*dy/\dz + -e^cos(x)*sin(x)*dx/\dy316sage: form2.diff()317-(1/y)/log(y)^2*dy/\dz + -e^cos(x)*sin(x)*dx/\dy318sage: d(form1) == form1.diff()319True320321The wedge product of two forms can be computed by means of the wedge322member function::323324sage: form1 = DifferentialForm(F, 2)325sage: form1[0, 1] = exp(z); form1326e^z*dx/\dy327sage: form2 = DifferentialForm(F, 1)328sage: form2[2] = exp(-z)329sage: form1.wedge(form2)330dx/\dy/\dz331332For this member function, there exists again a procedural function333which is completely equivalent::334335sage: from sage.tensor.differential_form_element import wedge336sage: form1.wedge(form2)337dx/\dy/\dz338sage: wedge(form1, form2)339dx/\dy/\dz340sage: form1.wedge(form2) == wedge(form1, form2)341True342343344NOTES:345346Differential forms are stored behind the screens as dictionaries,347where the keys are the subscripts of the non-zero components, and348the values are those components.349350For example, on a351space with coordinates x, y, z, the form352353f = sin(x*y) dx /\\ dy + exp(z) dy /\\ dz354355would be represented as the dictionary356357{(0, 1): sin(x*y), (1, 2): exp(z)}.358359Most differential forms are ''sparse'' in the sense that most of360their components are zero, so that this representation is more361efficient than storing all of the components in a vector.362363"""364365def __init__(self, parent, degree, fun = None):366r"""367Construct a differential form.368369INPUT:370371- ``parent`` -- Parent algebra of differential forms.372373- ``degree`` -- Degree of the differential form.374375- ``fun`` (default: None) -- Initialize this differential form with the given function. If the degree is not zero, this argument is silently ignored.376377EXAMPLES::378379sage: x, y, z = var('x, y, z')380sage: F = DifferentialForms(); F381Algebra of differential forms in the variables x, y, z382sage: f = DifferentialForm(F, 0, sin(z)); f383sin(z)384385"""386387from sage.tensor.differential_forms import DifferentialForms388if not isinstance(parent, DifferentialForms):389raise TypeError, "Parent not an algebra of differential forms."390391RingElement.__init__(self, parent)392393self._degree = degree394self._components = {}395396if degree == 0 and fun is not None:397self.__setitem__([], fun)398399400def __getitem__(self, subscript):401r"""402Return a given component of the differential form.403404INPUT:405406- ``subscript``: subscript of the component. Must be an integer407or a list of integers.408409410EXAMPLES::411412sage: x, y, z = var('x, y, z')413sage: F = DifferentialForms(); F414Algebra of differential forms in the variables x, y, z415sage: f = DifferentialForm(F, 0, sin(x*y)); f416sin(x*y)417sage: f[()]418sin(x*y)419420sage: df = f.diff(); df421y*cos(x*y)*dx + x*cos(x*y)*dy422sage: df[0]423y*cos(x*y)424sage: df[1]425x*cos(x*y)426sage: df[2]4270428"""429430if isinstance(subscript, (Integer, int)):431subscript = (subscript, )432else:433subscript = tuple(subscript)434435dim = self.parent().base_space().dim()436if any([s >= dim for s in subscript]):437raise ValueError, "Index out of bounds."438439if len(subscript) != self._degree:440raise TypeError, "%s is not a subscript of degree %s" %\441(subscript, self._degree)442443sign, subscript = sort_subscript(subscript)444445if subscript in self._components:446return sign*self._components[subscript]447else:448return 0449450451def __setitem__(self, subscript, fun):452r"""453Modify a given component of the differential form.454455INPUT:456457- ``subscript``: subscript of the component. Must be an integer or a list of integers.458459EXAMPLES::460461sage: F = DifferentialForms(); F462Algebra of differential forms in the variables x, y, z463sage: f = DifferentialForm(F, 2)464sage: f[1, 2] = x; f465x*dy/\dz466"""467468if isinstance(subscript, (Integer, int)):469subscript = (subscript, )470else:471subscript = tuple(subscript)472473dim = self.parent().base_space().dim()474if any([s >= dim for s in subscript]):475raise ValueError, "Index out of bounds."476477if len(subscript) != self._degree:478raise TypeError, "%s is not a subscript of degree %s" %\479(subscript, self._degree)480481sign, subscript = sort_subscript(subscript)482self._components[subscript] = sign*SR(fun)483484485def is_zero(self):486r"""487Return True if ``self`` is the zero form.488489EXAMPLES::490491sage: F = DifferentialForms()492sage: f = DifferentialForm(F, 1); f4930494sage: f.is_zero()495True496sage: f[1] = 1497sage: f.is_zero()498False499sage: f.diff()5000501sage: f.diff().is_zero()502True503"""504505self._cleanup()506return len(self._components) == 0507508509def degree(self):510r"""511Return the degree of self.512513EXAMPLES::514515sage: F = DifferentialForms(); F516Algebra of differential forms in the variables x, y, z517sage: f = DifferentialForm(F, 2)518sage: f[1, 2] = x; f519x*dy/\dz520sage: f.degree()5212522523The exterior differential increases the degree of forms by one::524525sage: g = f.diff(); g526dx/\dy/\dz527sage: g.degree()5283529"""530return self._degree531532533def __eq__(self, other):534r"""535Test whether two differential forms are equal.536537EXAMPLES::538539sage: F = DifferentialForms(); F540Algebra of differential forms in the variables x, y, z541sage: f = DifferentialForm(F, 2)542sage: f[1,2] = x; f543x*dy/\dz544sage: f == f545True546547sage: g = DifferentialForm(F, 3)548sage: g[0, 1, 2] = 1; g549dx/\dy/\dz550sage: f == g551False552sage: f.diff() == g553True554"""555if type(other) == type(self):556if self._degree != other._degree:557return False558else:559# TODO: the following two lines are where most of the560# execution time is spent.561self._cleanup()562other._cleanup()563564if len(self._components) != len(other._components):565return False566567568# We compare the component dictionary of both differential569# forms, keeping in mind that the set of keys is570# lexicographically ordered, so that we can simply iterate571# over both dictionaries in one go and compare (key, value)572# pairs as we go along.573574for (key1, val1), (key2, val2) in \575zip(self._components.iteritems(), \576other._components.iteritems()):577if key1 != key2 or str(val1) != str(val2):578return False579return True580else:581return False582583584def __ne__(self, other):585r"""586Test whether two differential forms are not equal.587588EXAMPLES::589590sage: F = DifferentialForms(); F591Algebra of differential forms in the variables x, y, z592sage: f = DifferentialForm(F, 2)593sage: f[1,2] = x; f594x*dy/\dz595sage: g = DifferentialForm(F, 3)596sage: g[0, 1, 2] = 1; g597dx/\dy/\dz598sage: f != g599True600"""601602603return not self.__eq__(other)604605606def _neg_(self):607r"""608Return the negative of self.609610EXAMPLES::611612sage: x, y, z = var('x, y, z')613sage: F = DifferentialForms()614sage: f = DifferentialForm(F, 1)615sage: f[0] = y616sage: f[1] = -x617sage: f618y*dx + -x*dy619sage: -f620-y*dx + x*dy621sage: -f == f._neg_()622True623"""624625neg = DifferentialForm(self.parent(), self._degree)626for comp in self._components:627neg._components[comp] = -self._components[comp]628return neg629630631def _add_(self, other):632r"""633Add self and other634635EXAMPLES::636637sage: x, y, z = var('x, y, z')638sage: F = DifferentialForms()639sage: f = DifferentialForm(F, 1)640sage: g = DifferentialForm(F, 1)641sage: f[0] = exp(x); f642e^x*dx643sage: g[1] = sin(y); g644sin(y)*dy645sage: f + g646e^x*dx + sin(y)*dy647sage: f + g == f._add_(g)648True649650Forms must have the same degree to be added::651652sage: h = DifferentialForm(F, 2)653sage: h[1, 2] = x; h654x*dy/\dz655sage: f + h656Traceback (most recent call last):657...658TypeError: Cannot add forms of degree 1 and 2659660"""661662if self.is_zero():663return other664if other.is_zero():665return self666667if self._degree != other._degree:668raise TypeError, \669"Cannot add forms of degree %s and %s" % \670(self._degree, other._degree)671672sumform = DifferentialForm(self.parent(), self._degree)673sumform._components = self._components.copy()674for comp, fun in other._components.items():675sumform[comp] += fun676677sumform._cleanup()678return sumform679680681def _sub_(self, other):682r"""683Subtract other from self.684685EXAMPLES::686687sage: x, y, z = var('x, y, z')688sage: F = DifferentialForms()689sage: f = DifferentialForm(F, 1)690sage: g = DifferentialForm(F, 1)691sage: f[0] = exp(x); f692e^x*dx693sage: g[1] = sin(y); g694sin(y)*dy695sage: f - g696e^x*dx + -sin(y)*dy697sage: f - g == f._sub_(g)698True699700Forms must have the same degree to be subtracted::701702sage: h = DifferentialForm(F, 2)703sage: h[1, 2] = x; h704x*dy/\dz705sage: f - h706Traceback (most recent call last):707...708TypeError: Cannot add forms of degree 1 and 2709710"""711return self._add_(-other)712713714def _cleanup(self):715r"""716Helper function to clean up self, i.e. to remove any717zero components from the dictionary of components.718719EXAMPLES::720721sage: F = DifferentialForms()722sage: f = DifferentialForm(F, 1)723sage: f[0] = 0724sage: f[1] = 1725sage: f[2] = 0726sage: f._dump_all()727{(2,): 0, (0,): 0, (1,): 1}728sage: f._cleanup()729sage: f._dump_all()730{(1,): 1}731732"""733zeros = []734735for comp in self._components:736if self._components[comp].is_zero():737zeros.append(comp)738739for comp in zeros:740del self._components[comp]741742743def _dump_all(self):744r"""745Helper function to dump the internal dictionary of form components.746747EXAMPLES::748749sage: x, y, z = var('x, y, z')750sage: F = DifferentialForms()751sage: f = DifferentialForm(F, 1)752sage: f[1] = exp(cos(x))753sage: f[2] = sin(ln(y))754sage: f755sin(log(y))*dz + e^cos(x)*dy756sage: f._dump_all()757{(2,): sin(log(y)), (1,): e^cos(x)}758sage: g = DifferentialForm(F, 2)759sage: g[1, 2] = x+y+z760sage: g761(x + y + z)*dy/\dz762sage: g._dump_all()763{(1, 2): x + y + z}764765"""766print self._components767768769def diff(self):770r"""771Compute the exterior differential of ``self``.772773EXAMPLES::774775sage: x, y, z = var('x, y, z')776sage: F = DifferentialForms()777sage: f = DifferentialForm(F, 0, sin(x*y)); f778sin(x*y)779sage: f.diff()780y*cos(x*y)*dx + x*cos(x*y)*dy781sage: g = DifferentialForm(F, 1)782sage: g[0] = y/2783sage: g[1] = -x/2784sage: g7851/2*y*dx + -1/2*x*dy786sage: g.diff()787-1*dx/\dy788sage: h = DifferentialForm(F, 2)789sage: h[0, 1] = exp(z)790sage: h.diff()791e^z*dx/\dy/\dz792793The square of the exterior differential operator is794identically zero::795796sage: f797sin(x*y)798sage: f.diff()799y*cos(x*y)*dx + x*cos(x*y)*dy800sage: f.diff().diff()8010802803sage: g.diff().diff()8040805806The exterior differential operator is a derivation of degree one807on the space of differential forms. In this example we import the808operator d() as a short-hand for having to call the diff()809member function.810811::812813sage: from sage.tensor.differential_form_element import d814sage: d(f)815y*cos(x*y)*dx + x*cos(x*y)*dy816817sage: d(f).wedge(g) + f.wedge(d(g))818(-x*y*cos(x*y) - sin(x*y))*dx/\dy819sage: d(f.wedge(g))820(-x*y*cos(x*y) - sin(x*y))*dx/\dy821822sage: d(f.wedge(g)) == d(f).wedge(g) + f.wedge(d(g))823True824"""825826diff_form = DifferentialForm(self.parent(), self._degree + 1)827828for comp in self._components:829fun = self._components[comp]830for n, coord in enumerate(self.parent().base_space().coordinates()):831diff_form[(n, ) + comp] += fun.differentiate(coord)832833diff_form._cleanup()834return diff_form835836837def derivative(self, *args, **kwargs):838r"""839Compute the exterior derivative of ``self``. This is the same as840calling the ``diff`` member function.841842843EXAMPLES::844845sage: x, y = var('x, y')846sage: U = CoordinatePatch((x, y))847sage: F = DifferentialForms(U)848sage: q = DifferentialForm(F, 1)849sage: q[0] = -y/2850sage: q[1] = x/2851sage: q.diff()852dx/\dy853sage: q.derivative()854dx/\dy855856Invoking ``diff`` on a differential form has the same effect as857calling this member function::858859sage: diff(q)860dx/\dy861sage: diff(q) == q.derivative()862True863864When additional arguments are supplied to ``diff``, an error is raised,865since only the exterior derivative has intrinsic meaning while866derivatives with respect to the coordinate variables (in whichever867way) are coordinate dependent, and hence not intrinsic.868869::870871sage: diff(q, x)872Traceback (most recent call last):873...874ValueError: Differentiation of a form does not take any arguments.875"""876877if len(args) > 0 or len(kwargs) > 0:878raise ValueError, "Differentiation of a form does not take any arguments."879return self.diff()880881882def wedge(self, other):883r"""884Returns the wedge product of ``self`` and other.885886EXAMPLES::887888sage: x, y, z = var('x, y, z')889sage: F = DifferentialForms()890sage: f = DifferentialForm(F, 1)891sage: f[0] = x^2892sage: f[1] = y893sage: f894x^2*dx + y*dy895sage: g = DifferentialForm(F, 1)896sage: g[2] = z^3897sage: g898z^3*dz899sage: f.wedge(g)900y*z^3*dy/\dz + x^2*z^3*dx/\dz901902The wedge product is graded commutative::903904sage: f.wedge(g)905y*z^3*dy/\dz + x^2*z^3*dx/\dz906sage: g.wedge(f)907-y*z^3*dy/\dz + -x^2*z^3*dx/\dz908sage: f.wedge(f)9090910911When the wedge product of forms belonging to different algebras912is computed, an error is raised::913914sage: x, y, p, q = var('x, y, p, q')915sage: F = DifferentialForms(CoordinatePatch((x, y)))916sage: G = DifferentialForms(CoordinatePatch((p, q)))917sage: f = DifferentialForm(F, 0, 1); f9181919sage: g = DifferentialForm(G, 0, x); g920x921sage: f.parent()922Algebra of differential forms in the variables x, y923sage: g.parent()924Algebra of differential forms in the variables p, q925sage: f.wedge(g)926Traceback (most recent call last):927...928TypeError: unsupported operand parents for wedge: 'Algebra of differential forms in the variables x, y' and 'Algebra of differential forms in the variables p, q'929930"""931932if self.parent() != other.parent():933raise TypeError, "unsupported operand parents for wedge: " +\934"\'%s\' and \'%s\'" % (self.parent(), other.parent())935936output = DifferentialForm(self.parent(), self._degree + other._degree)937if self._degree + other._degree > self.parent().ngens():938return output939940for lcomp, lfun in self._components.items():941for rcomp, rfun in other._components.items():942output[lcomp + rcomp] += lfun*rfun943944output._cleanup()945return output946947948949def _mul_(self, other):950r"""951Multiply self and other. This is identical to the wedge operator.952953EXAMPLES::954955sage: x, y, z = var('x, y, z')956sage: F = DifferentialForms()957sage: f = F.gen(0); f958dx959sage: g = F.gen(1); g960dy961sage: f*g962dx/\dy963sage: f.wedge(g)964dx/\dy965sage: f*g == f.wedge(g)966True967sage: f*g == f._mul_(g)968True969970"""971return self.wedge(other)972973974def _latex_(self):975r"""976Return a latex representation of self.977978EXAMPLES::979980sage: x, y, z = var('x, y, z')981sage: F = DifferentialForms()982sage: f = DifferentialForm(F, 1)983sage: f[1] = exp(z); f984e^z*dy985sage: latex(f)986e^{z} d y987sage: g = f.diff(); g988-e^z*dy/\dz989sage: latex(g)990-e^{z} d y \wedge d z991sage: latex(g) == g._latex_()992True993994"""995if len(self._components) == 0:996return '0'997998format = DifferentialFormFormatter(self.parent().base_space())999output = [format.latex(comp, fun) \1000for (comp, fun) in self._components.items()]1001return ' + '.join(output)100210031004def _repr_(self):1005r"""1006Return string representation of self.10071008EXAMPLES::10091010sage: x, y, z = var('x, y, z')1011sage: F = DifferentialForms()1012sage: f = DifferentialForm(F, 1)1013sage: f[1] = exp(z); f1014e^z*dy1015sage: print f1016e^z*dy1017sage: f._repr_()1018'e^z*dy'1019"""1020if len(self._components) == 0:1021return '0'10221023format = DifferentialFormFormatter(self.parent().base_space())1024output = [format.repr(comp, fun) \1025for (comp, fun) in self._components.items()]1026return ' + '.join(output)1027102810291030# Unsupported methods10311032def abs(self):1033"""1034Method not defined for differential forms.10351036EXAMPLES::10371038sage: F = DifferentialForms()1039sage: f = DifferentialForm(F, 1)1040sage: f.abs()1041Traceback (most recent call last):1042...1043NotImplementedError: Absolute value not defined for differential forms.10441045"""1046raise NotImplementedError, "Absolute value not defined for differential forms."104710481049def leading_coefficient(self, cmp=None):1050"""1051Method not defined for differential forms.10521053EXAMPLES::10541055sage: F = DifferentialForms()1056sage: f = DifferentialForm(F, 1)1057sage: f.leading_coefficient()1058Traceback (most recent call last):1059...1060NotImplementedError: leading_coefficient not defined for differential forms.10611062"""1063raise NotImplementedError, "leading_coefficient not defined for differential forms."106410651066def leading_item(self, cmp=None):1067"""1068Method not defined for differential forms.10691070EXAMPLES::10711072sage: F = DifferentialForms()1073sage: f = DifferentialForm(F, 1)1074sage: f.leading_item()1075Traceback (most recent call last):1076...1077NotImplementedError: leading_item not defined for differential forms.10781079"""1080raise NotImplementedError, "leading_item not defined for differential forms."108110821083def leading_monomial(self, cmp=None):1084"""1085Method not defined for differential forms.10861087EXAMPLES::10881089sage: F = DifferentialForms()1090sage: f = DifferentialForm(F, 1)1091sage: f.leading_monomial()1092Traceback (most recent call last):1093...1094NotImplementedError: leading_monomial not defined for differential forms.10951096"""1097raise NotImplementedError, "leading_monomial not defined for differential forms."109810991100def leading_support(self, cmp=None):1101"""1102Method not defined for differential forms.11031104EXAMPLES::11051106sage: F = DifferentialForms()1107sage: f = DifferentialForm(F, 1)1108sage: f.leading_support()1109Traceback (most recent call last):1110...1111NotImplementedError: leading_support not defined for differential forms.11121113"""1114raise NotImplementedError, "leading_support not defined for differential forms."111511161117def leading_term(self, cmp=None):1118"""1119Method not defined for differential forms.11201121EXAMPLES::11221123sage: F = DifferentialForms()1124sage: f = DifferentialForm(F, 1)1125sage: f.leading_term()1126Traceback (most recent call last):1127...1128NotImplementedError: leading_term not defined for differential forms.11291130"""1131raise NotImplementedError, "leading_term not defined for differential forms."113211331134def trailing_coefficient(self, cmp=None):1135"""1136Method not defined for differential forms.11371138EXAMPLES::11391140sage: F = DifferentialForms()1141sage: f = DifferentialForm(F, 1)1142sage: f.trailing_coefficient()1143Traceback (most recent call last):1144...1145NotImplementedError: trailing_coefficient not defined for differential forms.11461147"""1148raise NotImplementedError, "trailing_coefficient not defined for differential forms."114911501151def trailing_item(self, cmp=None):1152"""1153Method not defined for differential forms.11541155EXAMPLES::11561157sage: F = DifferentialForms()1158sage: f = DifferentialForm(F, 1)1159sage: f.trailing_item()1160Traceback (most recent call last):1161...1162NotImplementedError: leading_coefficient not defined for differential forms.11631164"""1165raise NotImplementedError, "leading_coefficient not defined for differential forms."116611671168def trailing_monomial(self, cmp=None):1169"""1170Method not defined for differential forms.11711172EXAMPLES::11731174sage: F = DifferentialForms()1175sage: f = DifferentialForm(F, 1)1176sage: f.trailing_monomial()1177Traceback (most recent call last):1178...1179NotImplementedError: trailing_monomial not defined for differential forms.11801181"""1182raise NotImplementedError, "trailing_monomial not defined for differential forms."118311841185def trailing_support(self, cmp=None):1186"""1187Method not defined for differential forms.11881189EXAMPLES::11901191sage: F = DifferentialForms()1192sage: f = DifferentialForm(F, 1)1193sage: f.trailing_support()1194Traceback (most recent call last):1195...1196NotImplementedError: trailing_support not defined for differential forms.11971198"""1199raise NotImplementedError, "trailing_support not defined for differential forms."120012011202def trailing_term(self, cmp=None):1203"""1204Method not defined for differential forms.12051206EXAMPLES::12071208sage: F = DifferentialForms()1209sage: f = DifferentialForm(F, 1)1210sage: f.trailing_term()1211Traceback (most recent call last):1212...1213NotImplementedError: trailing_term not defined for differential forms.12141215"""1216raise NotImplementedError, "trailing_term not defined for differential forms."121712181219def map_coefficients(self, f):1220"""1221Method not defined for differential forms.12221223EXAMPLES::12241225sage: F = DifferentialForms()1226sage: f = DifferentialForm(F, 1)1227sage: f.map_coefficients(lambda x: x)1228Traceback (most recent call last):1229...1230NotImplementedError: map_coefficients not defined for differential forms.12311232"""1233raise NotImplementedError, "map_coefficients not defined for differential forms."123412351236def map_item(self, f):1237"""1238Method not defined for differential forms.12391240EXAMPLES::12411242sage: F = DifferentialForms()1243sage: f = DifferentialForm(F, 1)1244sage: f.map_item(lambda x: x)1245Traceback (most recent call last):1246...1247NotImplementedError: map_item not defined for differential forms.12481249"""1250raise NotImplementedError, "map_item not defined for differential forms."125112521253def map_support(self, f):1254"""1255Method not defined for differential forms.12561257EXAMPLES::12581259sage: F = DifferentialForms()1260sage: f = DifferentialForm(F, 1)1261sage: f.map_support(lambda x: x)1262Traceback (most recent call last):1263...1264NotImplementedError: map_support not defined for differential forms.12651266"""1267raise NotImplementedError, "map_support not defined for differential forms."12681269127012711272def d(form):1273r"""1274Returns the exterior derivative of a given form, i.e. calls the diff()1275member function.12761277EXAMPLES::12781279sage: from sage.tensor.differential_form_element import d1280sage: x, y, z = var('x, y, z')1281sage: F = DifferentialForms()1282sage: f = DifferentialForm(F, 1)1283sage: f[2] = cos(x); f1284cos(x)*dz1285sage: d(f)1286-sin(x)*dx/\dz1287sage: f.diff()1288-sin(x)*dx/\dz1289sage: d(f) == f.diff()1290True1291"""1292return form.diff()129312941295def wedge(left, right):1296r"""1297Computes the wedge product of two forms, i.e. calls the wedge()1298member function.12991300EXAMPLES::13011302sage: from sage.tensor.differential_form_element import wedge1303sage: x, y, z = var('x, y, z')1304sage: F = DifferentialForms()1305sage: f = DifferentialForm(F, 1)1306sage: f[2] = cos(x); f1307cos(x)*dz1308sage: g = DifferentialForm(F, 1)1309sage: g[1] = sin(y); g1310sin(y)*dy1311sage: wedge(f, g)1312-sin(y)*cos(x)*dy/\dz1313sage: f.wedge(g)1314-sin(y)*cos(x)*dy/\dz1315sage: wedge(f, g) == f.wedge(g)1316True1317"""1318return left.wedge(right)131913201321