139 lines
3.9 KiB
Plaintext
139 lines
3.9 KiB
Plaintext
@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.
|