@q $Id: pyramid_prod.hweb 148 2005-04-19 15:12:26Z kamenik $ @> @q Copyright 2004, Ondra Kamenik @> @*2 Multiplying tensor columns. Start of {\tt pyramid\_prod.h} file. In here, we implement the Faa Di Bruno for folded tensors. Recall, that one step of the Faa Di Bruno is a formula: $$\left[B_{s^k}\right]_{\alpha_1\ldots\alpha_k}= [h_{y^l}]_{\gamma_1\ldots\gamma_l} \prod_{m=1}^l\left[g_{s^{\vert c_m\vert}}\right]^{\gamma_m}_{c_m(\alpha)} $$ In contrast to unfolded implementation of |UGSContainer::multAndAdd| with help of |KronProdAll| and |UPSTensor|, we take a completely different strategy. We cannot afford full instantiation of $$\sum_{c\in M_{l,k}} \prod_{m=1}^l\left[g_{s^{\vert c_m\vert}}\right]^{\gamma_m}_{c_m(\alpha)}$$ and therefore we do it per partes. We select some number of columns, for instance 10, calculate 10 continuous iterators of tensor $B$. Then we form unfolded tensor $$[G]_S^{\gamma_1\ldots\gamma_l}=\left[\sum_{c\in M_{l,k}} \prod_{m=1}^l\left[g_{s^{\vert c_m\vert}}\right]^{\gamma_m}_{c_m(\alpha)} \right]_S$$ where $S$ is the selected set of 10 indices. This is done as Kronecker product of vectors corresponding to selected columns. Note that, in general, there is no symmetry in $G$, its type is special class for this purpose. If $g$ is folded, then we have to form folded version of $G$. There is no symmetry in $G$ data, so we sum all unfolded indices corresponding to folded index together. This is perfectly OK, since we multiply these groups of (equivalent) items with the same number in fully symmetric $g$. After this, we perform ordinary matrix multiplication to obtain a selected set of columns of $B$. In here, we define a class for forming and representing $[G]_S^{\gamma_1\ldots\gamma_l}$. Basically, this tensor is row-oriented (multidimensional index is along rows), and it is fully symmetric. So we inherit from |URTensor|. If we need its folded version, we simply use a suitable conversion. The new abstraction will have only a new constructor allowing a construction from the given set of indices $S$, and given set of tensors $g$. The rest of the process is implemented in |@<|FGSContainer::multAndAdd| unfolded code@>| or |@<|FGSContainer::multAndAdd| folded code@>|. @c #ifndef PYRAMID_PROD_H #define PYRAMID_PROD_H #include "int_sequence.h" #include "rfs_tensor.h" #include "gs_tensor.h" #include "t_container.h" #include using namespace std; @<|USubTensor| class declaration@>; #endif @ Here we define the new tensor for representing $[G]_S^{\gamma_1\ldots\gamma_l}$. It allows a construction from container of folded general symmetry tensors |cont|, and set of indices |ts|. Also we have to supply dimensions of resulting tensor $B$, and dimensions of tensor $h$. @<|USubTensor| class declaration@>= class USubTensor : public URTensor { public:@; USubTensor(const TensorDimens& bdims, const TensorDimens& hdims, const FGSContainer& cont, const vector& lst); void addKronColumn(int i, const vector& ts, const IntSequence& pindex); }; @ End of {\tt pyramid\_prod.h} file.