1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
@q $Id: t_container.cweb 148 2005-04-19 15:12:26Z kamenik $ @>
@q Copyright 2004, Ondra Kamenik @>
@ Start of {\tt t\_container.cpp} file.
@s USubTensor int
@c
#include "t_container.h"
#include "kron_prod.h"
#include "ps_tensor.h"
#include "pyramid_prod.h"
const int FGSContainer::num_one_time = 10;
@<|UGSContainer| conversion from |FGSContainer|@>;
@<|UGSContainer::multAndAdd| code@>;
@<|FGSContainer| conversion from |UGSContainer|@>;
@<|FGSContainer::multAndAdd| folded code@>;
@<|FGSContainer::multAndAdd| unfolded code@>;
@<|FGSContainer::getIndices| code@>;
@
@<|UGSContainer| conversion from |FGSContainer|@>=
UGSContainer::UGSContainer(const FGSContainer& c)
: TensorContainer<UGSTensor>(c.num())
{
for (FGSContainer::const_iterator it = c.begin();
it != c.end(); ++it) {
UGSTensor* unfolded = new UGSTensor(*((*it).second));
insert(unfolded);
}
}
@ We set |l| to dimension of |t|, this is a tensor which multiplies
tensors from the container from the left. Also we set |k| to a
dimension of the resulting tensor. We go through all equivalences on
|k| element set and pickup only those which have $l$ classes.
In each loop, we fetch all necessary tensors for the product to the
vector |ts|. Then we form Kronecker product |KronProdAll| and feed it
with tensors from |ts|. Then we form unfolded permuted symmetry tensor
|UPSTensor| as matrix product of |t| and Kronecker product |kp|. Then
we add the permuted data to |out|. This is done by |UPSTensor| method
|addTo|.
@<|UGSContainer::multAndAdd| code@>=
void UGSContainer::multAndAdd(const UGSTensor& t, UGSTensor& out) const
{
int l = t.dimen();
int k = out.dimen();
const EquivalenceSet& eset = ebundle.get(k);
for (EquivalenceSet::const_iterator it = eset.begin();
it != eset.end(); ++it) {
if ((*it).numClasses() == l) {
vector<const UGSTensor*> ts =
fetchTensors(out.getSym(), *it);
KronProdAllOptim kp(l);
for (int i = 0; i < l; i++)
kp.setMat(i, *(ts[i]));
kp.optimizeOrder();
UPSTensor ups(out.getDims(), *it, t, kp);
ups.addTo(out);
}
}
}
@
@<|FGSContainer| conversion from |UGSContainer|@>=
FGSContainer::FGSContainer(const UGSContainer& c)
: TensorContainer<FGSTensor>(c.num())
{
for (UGSContainer::const_iterator it = c.begin();
it != c.end(); ++it) {
FGSTensor* folded = new FGSTensor(*((*it).second));
insert(folded);
}
}
@ Here we perform one step of the Faa Di Bruno operation. We call the
|multAndAdd| for unfolded tensor.
@<|FGSContainer::multAndAdd| folded code@>=
void FGSContainer::multAndAdd(const FGSTensor& t, FGSTensor& out) const
{
UGSTensor ut(t);
multAndAdd(ut, out);
}
@ This is the same as |@<|UGSContainer::multAndAdd| code@>|
but we do not construct |UPSTensor| from the Kronecker
product, but |FPSTensor|.
@<|FGSContainer::multAndAdd| unfolded code@>=
void FGSContainer::multAndAdd(const UGSTensor& t, FGSTensor& out) const
{
int l = t.dimen();
int k = out.dimen();
const EquivalenceSet& eset = ebundle.get(k);
for (EquivalenceSet::const_iterator it = eset.begin();
it != eset.end(); ++it) {
if ((*it).numClasses() == l) {
vector<const FGSTensor*> ts =
fetchTensors(out.getSym(), *it);
KronProdAllOptim kp(l);
for (int i = 0; i < l; i++)
kp.setMat(i, *(ts[i]));
kp.optimizeOrder();
FPSTensor fps(out.getDims(), *it, t, kp);
fps.addTo(out);
}
}
}
@ This fills a given vector with integer sequences corresponding to
first |num| indices from interval |start| (including) to |end|
(excluding). If there are not |num| of such indices, the shorter vector
is returned.
@<|FGSContainer::getIndices| code@>=
Tensor::index
FGSContainer::getIndices(int num, vector<IntSequence>& out,
const Tensor::index& start,
const Tensor::index& end)
{
out.clear();
int i = 0;
Tensor::index run = start;
while (i < num && run != end) {
out.push_back(run.getCoor());
i++;
++run;
}
return run;
}
@ End of {\tt t\_container.cpp} file.
|