@q $Id: fs_tensor.hweb 741 2006-05-09 11:12:46Z kamenik $ @> @q Copyright 2004, Ondra Kamenik @> @*2 Full symmetry tensor. Start of {\tt fs\_tensor.h} file. Here we define folded and unfolded tensors for full symmetry. All tensors from here are identifying the multidimensional index with columns. @c #ifndef FS_TENSOR_H #define FS_TENSOR_H #include "tensor.h" #include "symmetry.h" class FGSTensor; class UGSTensor; class FRSingleTensor; class FSSparseTensor; @<|FFSTensor| class declaration@>; @<|UFSTensor| class declaration@>; #endif @ Folded tensor with full symmetry maintains only information about number of symmetrical variables |nv|. Further, we implement what is left from the super class |FTensor|. We implement |getOffset| which should be used with care since its complexity. We implement a method adding a given general symmetry tensor to the full symmetry tensor supposing the variables of the general symmetry tensor are stacked giving only one variable of the full symmetry tensor. For instance, if $x=[y^T, u^T]^T$, then we can add tensor $\left[g_{y^2u}\right]$ to tensor $g_{x^3}$. This is done in method |addSubTensor|. Consult |@<|FGSTensor| class declaration@>| to know what is general symmetry tensor. @<|FFSTensor| class declaration@>= class UFSTensor; class FFSTensor : public FTensor { int nv; public:@; @<|FFSTensor| constructor declaration@>; void increment(IntSequence& v) const; void decrement(IntSequence& v) const; UTensor& unfold() const; Symmetry getSym() const {@+ return Symmetry(dimen());@+} int getOffset(const IntSequence& v) const; void addSubTensor(const FGSTensor& t); int nvar() const {@+return nv;@+} static int calcMaxOffset(int nvar, int d); }; @ Here are the constructors. The second constructor constructs a tensor by one-dimensional contraction from the higher dimensional tensor |t|. This is, it constructs a tensor $$\left[g_{y^n}\right]_{\alpha_1\ldots\alpha_n}= \left[t_{y^{n+1}}\right]_{\alpha_1\ldots\alpha_n\beta}[x]^\beta$$ See implementation |@<|FFSTensor| contraction constructor@>| for details. The next constructor converts from sparse tensor (which is fully symmetric and folded by nature). The fourth constructs object from unfolded fully symmetric. The fifth constructs a subtensor of selected rows. @<|FFSTensor| constructor declaration@>= FFSTensor(int r, int nvar, int d) : FTensor(along_col, IntSequence(d, nvar), r, calcMaxOffset(nvar, d), d), nv(nvar)@+ {} FFSTensor(const FFSTensor& t, const ConstVector& x); FFSTensor(const FSSparseTensor& t); FFSTensor(const FFSTensor& ft) : FTensor(ft), nv(ft.nv)@+ {} FFSTensor(const UFSTensor& ut); FFSTensor(int first_row, int num, FFSTensor& t) : FTensor(first_row, num, t), nv(t.nv)@+ {} @ Unfolded fully symmetric tensor is almost the same in structure as |FFSTensor|, but the method |unfoldData|. It takes columns which also exist in folded version and copies them to all their symmetrical locations. This is useful when constructing unfolded tensor from folded one. @<|UFSTensor| class declaration@>= class UFSTensor : public UTensor { int nv; public:@; @<|UFSTensor| constructor declaration@>; void increment(IntSequence& v) const; void decrement(IntSequence& v) const; FTensor& fold() const; Symmetry getSym() const {@+ return Symmetry(dimen());@+} int getOffset(const IntSequence& v) const; void addSubTensor(const UGSTensor& t); int nvar() const {@+ return nv;@+} static int calcMaxOffset(int nvar, int d) {@+ return power(nvar, d);@+} private:@; void unfoldData(); }; @ @<|UFSTensor| constructor declaration@>= UFSTensor(int r, int nvar, int d) : UTensor(along_col, IntSequence(d, nvar), r, calcMaxOffset(nvar, d), d), nv(nvar)@+ {} UFSTensor(const UFSTensor& t, const ConstVector& x); UFSTensor(const UFSTensor& ut) : UTensor(ut), nv(ut.nv)@+ {} UFSTensor(const FFSTensor& ft); UFSTensor(int first_row, int num, UFSTensor& t) : UTensor(first_row, num, t), nv(t.nv)@+ {} @ End of {\tt fs\_tensor.h} file.