# Differences

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

 — documentation:ref:product [2015/11/21 12:33] (current) Line 1: Line 1: + ====== Product ====== + ---- + + =====Basics===== + ''​Product''​ represents a product of terms. Like any other expression, it inherits all properties of [[Tensor]]. ''​Product''​ adopts the following convention on its indices: the indices of product are sorted concatenated indices of its multipliers:​ + + def t = '​f_ba*t^c_c*h^a'​.t + println t.indice + ​ + + > ^{ac}_{abc} + ​ + + ''​Product''​ sorts its arguments and collapses equal scalar terms into powers. ​ + + + ''​Product''​ is one of the most sophisticated entities in Redberry: contractions of indices brings additional structure of mathematical //graph// which is reflected in ''​Product''​ by introducing several methods to access graph structure of product. + + The data structure used to represent product contains three main blocks: numerical factor, subproduct of scalar factors (with ''​indices.size() == 0''​),​ and tensorial content (with ''​indices.size() != 0''​). Each block can be obtained via special additional methods introduced in product. + =====Additional features===== + There are several features in addition to those defined in [[Tensor]] that are inherent only in [[Product]]:​ + + <​html>​ + ​ +
<​code>​.select(positions)​ + ​returns a product of elements at specified positions ​ +
<​code>​.remove(positions)​ + ​returns a product with removed elements at specified positions ​ +
<​code>​.factor​ + ​returns a numerical factor of product ​ +
<​code>​.indexlessSubProduct​ + ​returns a subproduct of indexless terms, i.e. product of those terms which <​code>​indices.size() == 0 ​ +
<​code>​.dataSubProduct​ + ​returns a subproduct of indexed terms, i.e. product of those terms which <​code>​indices.size() != 0 ​ +
<​code>​.content​ + ​returns a data structure that allows to access <​i>​graph structure​ of product ​ +
+ + + + + + + + + + + + ​ + ​ + + Consider examples: + + def p = '​2*a*b*f_ba*t^c_c*h^a'​.t + println p.select(2, 3, 5) + ​ + + > a*t^{c}_{c}*h^{a} + ​ + + println p.remove(2, 3, 5) + ​ + + > 2*b*f_{ba} + ​ + + println p.factor + ​ + + > 2 + ​ + + println p.indexlessSubProduct + ​ + + > 2*b*a + ​ + + println p.dataSubProduct + ​ + + > t^{c}_{c}*f_{ba}*h^{a} + ​ + =====Advanced features: product content and graph structure ===== + The presence of indices bring a //graph structure// of Product: each multiplier represents a graph vertex, while contractions between indices are edges. One can check whether two graph isomorphic, i.e. that two tensors are equal to within free and dummy indices relabelling using [[documentation:​guide:​mappings_of_indices]]. + + There is a special property ''​.content'',​ which allows to access graph structure of ''​Product'';​ the object returned by ''​.content''​ called ''​ProductContent''​. It holds tensorial part of product and additional low-level data structures used in Redberry to represent tensorial graphs. Besides, ''​ProductContent''​ provides several useful methods like ''​.scalars''​ and ''​.nonScalar''​ which return array of scalar sub-products and non-scalar part of tensor respectively. Consider examples: + + def p = '​2*a*f_a*t^ba*g_b*t^i_i*t^mn*f_nmk'​.t + println p.size() + ​ + + > 8 + ​ + + def content = p.content + println content.size() + ​ + + > 6 + ​ + + println content[0..content.size()] + ​ + + > [f_a, t^ba, g_b, t^i_i, t^mn, f_nmk] + ​ + + println content.scalars + ​ + + > [t^{i}_{i}, t^{ba}*g_{b}*f_{a}] + ​ + + println content.nonScalar + ​ + + > t^{mn}*f_{nmk} + ​ + + In order to access low-level structure that encodes ''​Product''​ graph there is ''​.structureOfContractions''​ property in ''​ProductContent''​. This structure allows to check connected components of graph and check for each particular tensor ​ with which tensors it is contracted. ​ Without going into low-level details, let's illustrate this features by the examples: + + def p = '​3*c*f_i*g_b*t^i_i*t^pq*f_qpk*t^bie'​.t + def content = p.content + //get graph representation + def graph = content.structureOfContractions + //array of connected components + println graph.components + ​ + + > [0, 1, 0, 1, 2, 0] + ​ + The array of //​components//​ indicates whether two tensors belongs to the same  connected component of graph: two tensors at //i//-th and //j//-th positions belongs to the same component if + ''​components[i] == components[j]'',​ and ''​components[i]''​ is the number of corresponding component. + + //get position of tensor t^bie + def i = content.findIndexOf { it.equals('​t^bie'​.t) } + //​contractions of tensor t^bie + def contractions = graph.getContractedWith(i) + for (def c in contractions) { + if (c.tensor == -1)//free index + println "Free indices:"​ + content[i].indices[c.indicesFrom] + else { + println "With tensor: " + content[c.tensor] + println "This indices:"​ + content[i].indices[c.indicesFrom] + println "With indices:"​ + content[c.tensor].indices[c.indicesTo] + } + } + ​ + + > Free indices:​^{e} + > With tensor: g_{b} + > This indices:​^{b} + > With indices:​_{b} + > With tensor: f_{i} + > This indices:​^{i} + > With indices:​_{i} + ​ + =====See also===== + * Related guides: [[documentation:​guide:​tensors_and_indices]],​ [[documentation:​guide:​tree_traversal]],​ [[documentation:​guide:​mappings_of_indices]] + * Reference: [[documentation:​ref:​tensor]],​ [[documentation:​ref:​sum]],​ [[documentation:​ref:​indices]],​ [[documentation:​ref:​simpletensor]],​ [[documentation:​ref:​tensorfield]] + * JavaDocs: [[http://​api.redberry.cc/​redberry/​1.1.9/​java-api/​cc/​redberry/​core/​tensor/​Product.html| Product]] + * Source code: [[https://​bitbucket.org/​redberry/​redberry/​src/​tip/​core/​src/​main/​java/​cc/​redberry/​core/​tensor/​Product.java|Product.java]]