Differences

This shows you the differences between two versions of the page.

Link to this comparison view

documentation:guide:substitutions [2015/11/21 12:33] (current)
Line 1: Line 1:
 +====== Substitutions ======
 +<​html>​
 +<div class="​text-right"​ style="​font-size:​ 15px; ">
 +</​html>​
 +Next topic: [[documentation:​guide:​list_of_transformations]]
 +<​html>​
 +<span class="​glyphicon glyphicon-arrow-right"></​span>​
 +</​div>​
 +</​html>​
 +
 +----
 +
 +====Basics====
 +The most frequent transformation in all computations is a substitution. Here
 +we shall discuss the usage aspects of substitutions,​ while the idea of the
 +underlying algorithms can be found in [[documentation:​guide:​Mappings of Indices]].
 +
 +
 +
 +The very important feature of any tensorial CAS is automatic relabelling
 +of dummy indices in the case of dummy indices clash. Redberry takes care about
 +it in all types of substitutions. Consider, for example, the following simple
 +substitution:​
 +\[ x = x_a{}^a \qquad\text{in}\qquad ​ (x\, f_a + y_a) (x \, f_b + z_b) \]
 +Here is a code to perform this substitution in Redberry:
 +<sxh groovy; gutter: false>
 +def s = 'x = x_a^a'​.t
 +def t = '​(x*f_a + y_a)*(x*f_b + z_b)'​.t
 +println s >> t
 +</​sxh>​
 +<sxh plain; gutter: false>
 +   > (x_{d}^{d}*f_{a}+y_{a})*(x_{c}^{c}*f_{b}+z_{b})
 +</​sxh>​
 +As one can see, the appropriate relabelling was performed automatically. ​
 +
 +====Substitutions of tensor fields====
 +Redberry supports substitutions of [[documentation:​ref:​TensorField|tensorial functions]] and automatically performs matching of function arguments during substitution:​
 +<sxh groovy; gutter: false>
 +def s = '​F_ij[x_m,​ y_m] = x_i*y_j'​.t
 +def t = '​T^ab*F_ab[p^a - q^a, p^a + q^a]'​.t
 +println s >> t
 +</​sxh>​
 +<sxh plain; gutter: false>
 +   > T^{ab}*(p_{a}-q_{a})*(p_{b}+q_{b})
 +</​sxh>​
 +If [[documentation:​ref:​TensorField]] depends on indexed argument, then some ambiguities arise when mapping the arguments. For example, the following substitution:​
 + ​\[  ​
 +F_i (x_{mn}) \,=\, x_{ij} f^j \qquad \rightarrow \qquad F_k(x_i\,​y_j) ​
 +\] 
 +can be performed in two different ways: (a) matching $x_{ij} \to x_i y_j$ gives $x_k y_j f^j$, (b) matching $x_{ij} \to x_j y_i$ gives $y_k x_j f^j$. This is because the indices of product ($x_i y_j$) are not ordered by their nature. To explicitly specify the matching rule in such ambiguous situations, Redberry allows to enter the correspondence of indices in the field arguments: ​
 +<sxh groovy; gutter: true>
 +def s = '​F_i[x_mn] = x_ik*f^k'​.t
 +def t = '​F_k[x_i*y_j]'​.t //​equivalent to F_k[x_i*y_j:​_ij]
 +println s >> t
 +</​sxh>​
 +<sxh plain; gutter: false>
 +   > x_{k}*y_{a}*f^{a}
 +</​sxh>​
 +<sxh groovy; gutter: true; first-line: 4>
 +t = '​F_k[x_i*y_j:​_ji]'​.t ​
 +println s >> t
 +</​sxh>​
 +<sxh plain; gutter: false>
 +   > x_{a}*y_{k}*f^{a}
 +</​sxh>​
 + 
 +====Substitutions of products, sums, etc. ====
 +As well as [[documentation:​ref:​SimpleTensor]] and [[documentation:​ref:​TensorField]] substitutions,​ Redberry fully supports all other types of substitutions,​ taking into account both indices symmetries and indices contractions. Consider the following complicated example. Let's apply the following substitution ​
 +\[
 +f_{m} + R_{bma}\,​F^{ba} - R_{ljm}\,​F^{lj} =  R_{bam}\,​F^{ab}
 +\]
 +to tensor
 +\[
 +f_i + R_{ijk} F^{jk} + R_{ijk}\,​F^{kj} - R_{kij}\,​F^{jk},​
 +\]
 +where $R_{abc}$ is antisymmetric:​ \( R_{abc} \,=\, - R_{cba}\). It is easy to show that the result will be zero. In Redberry one can e.g. do
 +<sxh groovy; gutter: false>
 +addSymmetry '​R_mnp',​ -[[0, 2]].p
 +def s = 'f_m + R_bma*F^ba - R_ljm*F^lj =  R_bam*F^ab'​.t
 +def t = 'f_i + R_ijk*F^jk + R_ijk*F^kj - R_kij*F^jk'​.t
 +println s >> t
 +</​sxh>​
 +<sxh plain; gutter: false>
 +   > 0
 +</​sxh>​
 +We see, that Redberry matched the l.h.s. of the substitution in tensor ''​t''​ and automatically reduced the resulting sum to the standard form,  which, in turn, gave zero.
 +
 +Redberry takes into account not only predefined symmetries of simple
 +tensors, but also symmetries of any complicated expression, which arise from
 +its structure. For example:
 +<sxh groovy; gutter: false>
 +def s = 'K_a * (A^ab - A^ba) = F^a*A_a^b'​.t
 +def t = 'K_p * (A^qp - A^pq) + F^b*A_b^q'​.t
 +println s >> t
 +</​sxh>​
 +<sxh plain; gutter: false>
 +   > 0
 +</​sxh>​
 +The result is zero since tensor $(A_{cb} - A_{bc})$ is antisymmetric. As well,
 +Redberry takes care about symmetries of indexless objects:
 +<sxh groovy; gutter: false>
 +def c = 'Cos[a - b] = c'.t,
 +    s = 'Sin[a - b] = s'.t,
 +    t = 'x = Cos[b - a]**3 + Sin[b - a]**3'​.t
 +println (c | s) >> t
 +</​sxh>​
 +<sxh plain; gutter: false>
 +   > x = c**3 - s**3 
 +</​sxh>​
 +As one can see, the built-in definitions of sine and cosine are set up to be
 +odd and even respectively.
 +
 +====Sequential vs. simultaneous substitutions====
 +There is an important note on applying several substitutions at a time using the
 +joining of transformations. Substitutions joined with ''&''​ operator
 +will be applied sequentially. However, sometimes it is necessary to apply
 +several substitution rules "​simultaneously"​. Consider the following example:
 +<sxh groovy; gutter: false>
 +def X2YandY2X = '​x=y'​.t & '​y=x'​.t,​
 +    X2YorY2X ​ = '​x=y'​.t | '​y=x'​.t,​
 +    tensor = '​x+2*y'​.t ​   ​
 +println X2YandY2X >> tensor
 +</​sxh>​
 +<sxh plain; gutter: false>
 +   > 3*x
 +</​sxh>​
 +<sxh groovy; gutter: false>
 +println X2YorY2X >> tensor
 +</​sxh>​
 +<sxh plain; gutter: false>
 +   > y+2*x
 +</​sxh>​
 +The first transformation (''​X2YandY2X''​) means just sequential applying
 +of two provided substitutions,​ while the second (''​X2YorY2X''​)
 +performs both substitutions "​simultaneously"​.
 +
 +
 +====Constructing substitutions====
 +Sometimes it is necessary to create substitution from a given l.h.s and r.h.s that are raised from other calculations (not entered "by hand"​). In order to construct such expression programmatically from a given l.h.s. and r.h.s. one can use the following syntax:
 +<sxh groovy; gutter: false>
 + def lhs = '​x'​.t,​
 +    rhs = 'a + b'.t
 +//this is equivalent to subs = 'x = a + b'.t
 +def subs = lhs.eq(rhs)
 +//or equivalently
 +subs = "$lhs = $rhs"​.t
 +println subs >> '​x**2'​.t
 +</​sxh>​
 +<sxh plain; gutter: false>
 +   > (a + b)**2
 +</​sxh>​
 +
 +====See also====
 +  * Related guides: [[documentation:​guide:​applying_and_manipulating_transformations]],​ [[documentation:​guide:​list_of_transformations]]