Dynare++ tensor library: various simplifications/modernizations

time-shift
Sébastien Villemot 2019-02-12 17:30:10 +01:00
parent d9f0345213
commit 002e3d3770
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
20 changed files with 265 additions and 307 deletions

View File

@ -4,7 +4,7 @@
#include "permutation.hh" #include "permutation.hh"
#include "tl_exception.hh" #include "tl_exception.hh"
#include <cstring> #include <iostream>
int int
OrdSequence::operator[](int i) const OrdSequence::operator[](int i) const
@ -93,12 +93,12 @@ OrdSequence::average() const
/* Debug print. */ /* Debug print. */
void void
OrdSequence::print(const char *prefix) const OrdSequence::print(const std::string &prefix) const
{ {
printf("%s", prefix); std::cout << prefix;
for (int i : data) for (int i : data)
printf("%d ", i); std::cout << i << ' ';
printf("\n"); std::cout << '\n';
} }
Equivalence::Equivalence(int num) Equivalence::Equivalence(int num)
@ -112,7 +112,7 @@ Equivalence::Equivalence(int num)
} }
} }
Equivalence::Equivalence(int num, const char *dummy) Equivalence::Equivalence(int num, const std::string &dummy)
: n(num) : n(num)
{ {
OrdSequence s; OrdSequence s;
@ -121,12 +121,7 @@ Equivalence::Equivalence(int num, const char *dummy)
classes.push_back(s); classes.push_back(s);
} }
/* Copy constructors. The second also glues a given couple. */ /* Copy constructor that also glues a given couple. */
Equivalence::Equivalence(const Equivalence &e)
= default;
Equivalence::Equivalence(const Equivalence &e, int i1, int i2) Equivalence::Equivalence(const Equivalence &e, int i1, int i2)
: n(e.n), : n(e.n),
@ -144,15 +139,6 @@ Equivalence::Equivalence(const Equivalence &e, int i1, int i2)
} }
} }
const Equivalence &
Equivalence::operator=(const Equivalence &e)
{
classes.clear();
n = e.n;
classes = e.classes;
return *this;
}
bool bool
Equivalence::operator==(const Equivalence &e) const Equivalence::operator==(const Equivalence &e) const
{ {
@ -173,7 +159,7 @@ Equivalence::findHaving(int i) const
auto si = classes.begin(); auto si = classes.begin();
while (si != classes.end()) while (si != classes.end())
{ {
if ((*si).has(i)) if (si->has(i))
return si; return si;
++si; ++si;
} }
@ -188,7 +174,7 @@ Equivalence::findHaving(int i)
auto si = classes.begin(); auto si = classes.begin();
while (si != classes.end()) while (si != classes.end())
{ {
if ((*si).has(i)) if (si->has(i))
return si; return si;
++si; ++si;
} }
@ -251,7 +237,7 @@ Equivalence::trace(IntSequence &out, int num) const
int i = 0; int i = 0;
int nc = 0; int nc = 0;
for (auto it = begin(); it != end() && nc < num; ++it, ++nc) for (auto it = begin(); it != end() && nc < num; ++it, ++nc)
for (int j = 0; j < (*it).length(); j++, i++) for (int j = 0; j < it->length(); j++, i++)
{ {
TL_RAISE_IF(i >= out.size(), TL_RAISE_IF(i >= out.size(),
"Wrong size of output sequence in Equivalence::trace"); "Wrong size of output sequence in Equivalence::trace");
@ -270,22 +256,22 @@ Equivalence::trace(IntSequence &out, const Permutation &per) const
for (int iclass = 0; iclass < numClasses(); iclass++) for (int iclass = 0; iclass < numClasses(); iclass++)
{ {
auto itper = find(per.getMap()[iclass]); auto itper = find(per.getMap()[iclass]);
for (int j = 0; j < (*itper).length(); j++, i++) for (int j = 0; j < itper->length(); j++, i++)
out[i] = (*itper)[j]; out[i] = (*itper)[j];
} }
} }
/* Debug print. */ /* Debug print. */
void void
Equivalence::print(const char *prefix) const Equivalence::print(const std::string &prefix) const
{ {
int i = 0; int i = 0;
for (auto it = classes.begin(); for (auto it = classes.begin();
it != classes.end(); it != classes.end();
++it, i++) ++it, i++)
{ {
printf("%sclass %d: ", prefix, i); std::cout << prefix << "class " << i << ": ";
(*it).print(""); it->print("");
} }
} }
@ -310,8 +296,7 @@ Equivalence::print(const char *prefix) const
(since it is constructed by gluing attempts). */ (since it is constructed by gluing attempts). */
EquivalenceSet::EquivalenceSet(int num) EquivalenceSet::EquivalenceSet(int num)
: n(num), : n(num)
equis()
{ {
std::list<Equivalence> added; std::list<Equivalence> added;
Equivalence first(n); Equivalence first(n);
@ -323,10 +308,7 @@ EquivalenceSet::EquivalenceSet(int num)
added.pop_front(); added.pop_front();
} }
if (n > 1) if (n > 1)
{ equis.emplace_back(n, "");
Equivalence last(n, "");
equis.push_back(last);
}
} }
/* This method is used in |addParents| and returns |true| if the object /* This method is used in |addParents| and returns |true| if the object
@ -371,25 +353,23 @@ EquivalenceSet::addParents(const Equivalence &e,
if (!has(ns)) if (!has(ns))
{ {
added.push_back(ns); added.push_back(ns);
equis.push_back(ns); equis.push_back(std::move(ns));
} }
} }
} }
/* Debug print. */ /* Debug print. */
void void
EquivalenceSet::print(const char *prefix) const EquivalenceSet::print(const std::string &prefix) const
{ {
char tmp[100];
strcpy(tmp, prefix);
strcat(tmp, " ");
int i = 0; int i = 0;
for (auto it = equis.begin(); for (auto it = equis.begin();
it != equis.end(); it != equis.end();
++it, i++) ++it, i++)
{ {
printf("%sequivalence %d:(classes %d)\n", prefix, i, (*it).numClasses()); std::cout << prefix << "equivalence " << i << ":(classes "
(*it).print(tmp); << it->numClasses() << ")\n";
it->print(prefix + " ");
} }
} }
@ -404,15 +384,13 @@ EquivalenceBundle::EquivalenceBundle(int nmax)
const EquivalenceSet & const EquivalenceSet &
EquivalenceBundle::get(int n) const EquivalenceBundle::get(int n) const
{ {
if (n > (int) (bundle.size()) || n < 1) if (n > static_cast<int>(bundle.size()) || n < 1)
{ {
TL_RAISE("Equivalence set not found in EquivalenceBundle::get"); TL_RAISE("Equivalence set not found in EquivalenceBundle::get");
return bundle[0]; return bundle[0];
} }
else else
{ return bundle[n-1];
return bundle[n-1];
}
} }
/* Get |curmax| which is a maximum size in the bundle, and generate for /* Get |curmax| which is a maximum size in the bundle, and generate for

View File

@ -43,6 +43,7 @@
#include <vector> #include <vector>
#include <list> #include <list>
#include <string>
/* Here is the abstraction for an equivalence class. We implement it as /* Here is the abstraction for an equivalence class. We implement it as
|vector<int>|. We have a constructor for empty class, copy |vector<int>|. We have a constructor for empty class, copy
@ -58,11 +59,10 @@ public:
OrdSequence() : data() OrdSequence() : data()
{ {
} }
OrdSequence(const OrdSequence &s) OrdSequence(const OrdSequence &) = default;
= default; OrdSequence(OrdSequence &&) = default;
OrdSequence & OrdSequence &operator=(const OrdSequence &) = default;
operator=(const OrdSequence &s) OrdSequence &operator=(OrdSequence &&) = default;
= default;
bool operator==(const OrdSequence &s) const; bool operator==(const OrdSequence &s) const;
int operator[](int i) const; int operator[](int i) const;
bool operator<(const OrdSequence &s) const; bool operator<(const OrdSequence &s) const;
@ -79,7 +79,7 @@ public:
void add(int i); void add(int i);
void add(const OrdSequence &s); void add(const OrdSequence &s);
bool has(int i) const; bool has(int i) const;
void print(const char *prefix) const; void print(const std::string &prefix) const;
private: private:
double average() const; double average() const;
}; };
@ -107,11 +107,13 @@ public:
The third is the copy constructor. And the fourth is the copy The third is the copy constructor. And the fourth is the copy
constructor plus gluing |i1| and |i2| in one class. */ constructor plus gluing |i1| and |i2| in one class. */
Equivalence(int num); Equivalence(int num);
Equivalence(int num, const char *dummy); Equivalence(int num, const std::string &dummy);
Equivalence(const Equivalence &e); Equivalence(const Equivalence &) = default;
Equivalence(Equivalence &&) = default;
Equivalence(const Equivalence &e, int i1, int i2); Equivalence(const Equivalence &e, int i1, int i2);
const Equivalence &operator=(const Equivalence &e); Equivalence &operator=(const Equivalence &) = default;
Equivalence &operator=(Equivalence &&) = default;
bool operator==(const Equivalence &e) const; bool operator==(const Equivalence &e) const;
bool bool
operator!=(const Equivalence &e) const operator!=(const Equivalence &e) const
@ -135,7 +137,7 @@ public:
trace(out, numClasses()); trace(out, numClasses());
} }
void trace(IntSequence &out, const Permutation &per) const; void trace(IntSequence &out, const Permutation &per) const;
void print(const char *prefix) const; void print(const std::string &prefix) const;
seqit seqit
begin() begin()
{ {
@ -185,7 +187,7 @@ class EquivalenceSet
public: public:
using const_iterator = std::list<Equivalence>::const_iterator; using const_iterator = std::list<Equivalence>::const_iterator;
EquivalenceSet(int num); EquivalenceSet(int num);
void print(const char *prefix) const; void print(const std::string &prefix) const;
const_iterator const_iterator
begin() const begin() const
{ {
@ -214,7 +216,7 @@ class EquivalenceBundle
public: public:
EquivalenceBundle(int nmax); EquivalenceBundle(int nmax);
~EquivalenceBundle() = default; ~EquivalenceBundle() = default;
const EquivalenceSet&get(int n) const; const EquivalenceSet &get(int n) const;
void generateUpTo(int nmax); void generateUpTo(int nmax);
}; };

View File

@ -16,7 +16,7 @@
by an appropriate item of |x| and added to the column of $[g]$ tensor. */ by an appropriate item of |x| and added to the column of $[g]$ tensor. */
FFSTensor::FFSTensor(const FFSTensor &t, const ConstVector &x) FFSTensor::FFSTensor(const FFSTensor &t, const ConstVector &x)
: FTensor(along_col, IntSequence(t.dimen()-1, t.nvar()), : FTensor(indor::along_col, IntSequence(t.dimen()-1, t.nvar()),
t.nrows(), calcMaxOffset(t.nvar(), t.dimen()-1), t.dimen()-1), t.nrows(), calcMaxOffset(t.nvar(), t.dimen()-1), t.dimen()-1),
nv(t.nvar()) nv(t.nvar())
{ {
@ -32,7 +32,7 @@ FFSTensor::FFSTensor(const FFSTensor &t, const ConstVector &x)
for (int i = 0; i < nvar(); i++) for (int i = 0; i < nvar(); i++)
{ {
IntSequence from_ind(i, to.getCoor()); IntSequence from_ind(i, to.getCoor());
Tensor::index from(&t, from_ind); Tensor::index from(t, from_ind);
addColumn(x[i], t, *from, *to); addColumn(x[i], t, *from, *to);
} }
} }
@ -55,14 +55,14 @@ FFSTensor::calcMaxOffset(int nvar, int d)
/* The conversion from sparse tensor is clear. We go through all the /* The conversion from sparse tensor is clear. We go through all the
tensor and write to the dense what is found. */ tensor and write to the dense what is found. */
FFSTensor::FFSTensor(const FSSparseTensor &t) FFSTensor::FFSTensor(const FSSparseTensor &t)
: FTensor(along_col, IntSequence(t.dimen(), t.nvar()), : FTensor(indor::along_col, IntSequence(t.dimen(), t.nvar()),
t.nrows(), calcMaxOffset(t.nvar(), t.dimen()), t.dimen()), t.nrows(), calcMaxOffset(t.nvar(), t.dimen()), t.dimen()),
nv(t.nvar()) nv(t.nvar())
{ {
zeros(); zeros();
for (const auto & it : t.getMap()) for (const auto & it : t.getMap())
{ {
index ind(this, it.first); index ind(*this, it.first);
get(it.second.first, *ind) = it.second.second; get(it.second.first, *ind) = it.second.second;
} }
} }
@ -73,13 +73,13 @@ FFSTensor::FFSTensor(const FSSparseTensor &t)
copy the column. */ copy the column. */
FFSTensor::FFSTensor(const UFSTensor &ut) FFSTensor::FFSTensor(const UFSTensor &ut)
: FTensor(along_col, IntSequence(ut.dimen(), ut.nvar()), : FTensor(indor::along_col, IntSequence(ut.dimen(), ut.nvar()),
ut.nrows(), calcMaxOffset(ut.nvar(), ut.dimen()), ut.dimen()), ut.nrows(), calcMaxOffset(ut.nvar(), ut.dimen()), ut.dimen()),
nv(ut.nvar()) nv(ut.nvar())
{ {
for (index in = begin(); in != end(); ++in) for (index in = begin(); in != end(); ++in)
{ {
index src(&ut, in.getCoor()); index src(ut, in.getCoor());
copyColumn(ut, *src, *in); copyColumn(ut, *src, *in);
} }
} }
@ -156,7 +156,7 @@ FFSTensor::addSubTensor(const FGSTensor &t)
IntSequence c(ind.getCoor()); IntSequence c(ind.getCoor());
c.add(1, shift); c.add(1, shift);
c.sort(); c.sort();
Tensor::index tar(this, c); Tensor::index tar(*this, c);
addColumn(t, *ind, *tar); addColumn(t, *ind, *tar);
} }
} }
@ -167,7 +167,7 @@ FFSTensor::addSubTensor(const FGSTensor &t)
regularity of the unfolded tensor. */ regularity of the unfolded tensor. */
UFSTensor::UFSTensor(const UFSTensor &t, const ConstVector &x) UFSTensor::UFSTensor(const UFSTensor &t, const ConstVector &x)
: UTensor(along_col, IntSequence(t.dimen()-1, t.nvar()), : UTensor(indor::along_col, IntSequence(t.dimen()-1, t.nvar()),
t.nrows(), calcMaxOffset(t.nvar(), t.dimen()-1), t.dimen()-1), t.nrows(), calcMaxOffset(t.nvar(), t.dimen()-1), t.dimen()-1),
nv(t.nvar()) nv(t.nvar())
{ {
@ -190,13 +190,13 @@ UFSTensor::UFSTensor(const UFSTensor &t, const ConstVector &x)
columns of folded tensor, and then call |unfoldData()|. */ columns of folded tensor, and then call |unfoldData()|. */
UFSTensor::UFSTensor(const FFSTensor &ft) UFSTensor::UFSTensor(const FFSTensor &ft)
: UTensor(along_col, IntSequence(ft.dimen(), ft.nvar()), : UTensor(indor::along_col, IntSequence(ft.dimen(), ft.nvar()),
ft.nrows(), calcMaxOffset(ft.nvar(), ft.dimen()), ft.dimen()), ft.nrows(), calcMaxOffset(ft.nvar(), ft.dimen()), ft.dimen()),
nv(ft.nvar()) nv(ft.nvar())
{ {
for (index src = ft.begin(); src != ft.end(); ++src) for (index src = ft.begin(); src != ft.end(); ++src)
{ {
index in(this, src.getCoor()); index in(*this, src.getCoor());
copyColumn(ft, *src, *in); copyColumn(ft, *src, *in);
} }
unfoldData(); unfoldData();
@ -266,7 +266,7 @@ UFSTensor::addSubTensor(const UGSTensor &t)
c.add(-1, shift); c.add(-1, shift);
if (c.isPositive() && c.less(t.getDims().getNVX())) if (c.isPositive() && c.less(t.getDims().getNVX()))
{ {
Tensor::index from(&t, c); Tensor::index from(t, c);
addColumn(t, *from, *tar); addColumn(t, *from, *tar);
} }
} }
@ -283,7 +283,7 @@ UFSTensor::unfoldData()
{ {
IntSequence v(in.getCoor()); IntSequence v(in.getCoor());
v.sort(); v.sort();
index tmp(this, v); index tmp(*this, v);
copyColumn(*tmp, *in); copyColumn(*tmp, *in);
} }
} }

View File

@ -52,7 +52,7 @@ public:
The fifth constructs a subtensor of selected rows. */ The fifth constructs a subtensor of selected rows. */
FFSTensor(int r, int nvar, int d) FFSTensor(int r, int nvar, int d)
: FTensor(along_col, IntSequence(d, nvar), : FTensor(indor::along_col, IntSequence(d, nvar),
r, calcMaxOffset(nvar, d), d), nv(nvar) r, calcMaxOffset(nvar, d), d), nv(nvar)
{ {
} }
@ -97,7 +97,7 @@ class UFSTensor : public UTensor
int nv; int nv;
public: public:
UFSTensor(int r, int nvar, int d) UFSTensor(int r, int nvar, int d)
: UTensor(along_col, IntSequence(d, nvar), : UTensor(indor::along_col, IntSequence(d, nvar),
r, calcMaxOffset(nvar, d), d), nv(nvar) r, calcMaxOffset(nvar, d), d), nv(nvar)
{ {
} }

View File

@ -138,13 +138,13 @@ TensorDimens::decrement(IntSequence &v) const
/* Here we go through columns of folded, calculate column of unfolded, /* Here we go through columns of folded, calculate column of unfolded,
and copy data. */ and copy data. */
FGSTensor::FGSTensor(const UGSTensor &ut) FGSTensor::FGSTensor(const UGSTensor &ut)
: FTensor(along_col, ut.tdims.getNVX(), ut.nrows(), : FTensor(indor::along_col, ut.tdims.getNVX(), ut.nrows(),
ut.tdims.calcFoldMaxOffset(), ut.dimen()), ut.tdims.calcFoldMaxOffset(), ut.dimen()),
tdims(ut.tdims) tdims(ut.tdims)
{ {
for (index ti = begin(); ti != end(); ++ti) for (index ti = begin(); ti != end(); ++ti)
{ {
index ui(&ut, ti.getCoor()); index ui(ut, ti.getCoor());
copyColumn(ut, *ui, *ti); copyColumn(ut, *ui, *ti);
} }
} }
@ -160,7 +160,7 @@ FGSTensor::FGSTensor(const UGSTensor &ut)
obtain coordinates in the |this| tensor and we copy the item. */ obtain coordinates in the |this| tensor and we copy the item. */
FGSTensor::FGSTensor(const FSSparseTensor &t, const IntSequence &ss, FGSTensor::FGSTensor(const FSSparseTensor &t, const IntSequence &ss,
const IntSequence &coor, const TensorDimens &td) const IntSequence &coor, const TensorDimens &td)
: FTensor(along_col, td.getNVX(), t.nrows(), : FTensor(indor::along_col, td.getNVX(), t.nrows(),
td.calcFoldMaxOffset(), td.dimen()), td.calcFoldMaxOffset(), td.dimen()),
tdims(td) tdims(td)
{ {
@ -192,7 +192,7 @@ FGSTensor::FGSTensor(const FSSparseTensor &t, const IntSequence &ss,
{ {
IntSequence c((*run).first); IntSequence c((*run).first);
c.add(-1, lb); c.add(-1, lb);
Tensor::index ind(this, c); Tensor::index ind(*this, c);
TL_RAISE_IF(*ind < 0 || *ind >= ncols(), TL_RAISE_IF(*ind < 0 || *ind >= ncols(),
"Internal error in slicing constructor of FGSTensor"); "Internal error in slicing constructor of FGSTensor");
get((*run).second.first, *ind) = (*run).second.second; get((*run).second.first, *ind) = (*run).second.second;
@ -204,7 +204,7 @@ FGSTensor::FGSTensor(const FSSparseTensor &t, const IntSequence &ss,
/* The code is similar to |@<|FGSTensor| slicing from |FSSparseTensor|@>|. */ /* The code is similar to |@<|FGSTensor| slicing from |FSSparseTensor|@>|. */
FGSTensor::FGSTensor(const FFSTensor &t, const IntSequence &ss, FGSTensor::FGSTensor(const FFSTensor &t, const IntSequence &ss,
const IntSequence &coor, const TensorDimens &td) const IntSequence &coor, const TensorDimens &td)
: FTensor(along_col, td.getNVX(), t.nrows(), : FTensor(indor::along_col, td.getNVX(), t.nrows(),
td.calcFoldMaxOffset(), td.dimen()), td.calcFoldMaxOffset(), td.dimen()),
tdims(td) tdims(td)
{ {
@ -226,8 +226,8 @@ FGSTensor::FGSTensor(const FFSTensor &t, const IntSequence &ss,
} }
zeros(); zeros();
Tensor::index lbi(&t, lb); Tensor::index lbi(t, lb);
Tensor::index ubi(&t, ub); Tensor::index ubi(t, ub);
++ubi; ++ubi;
for (Tensor::index run = lbi; run != ubi; ++run) for (Tensor::index run = lbi; run != ubi; ++run)
{ {
@ -235,7 +235,7 @@ FGSTensor::FGSTensor(const FFSTensor &t, const IntSequence &ss,
{ {
IntSequence c(run.getCoor()); IntSequence c(run.getCoor());
c.add(-1, lb); c.add(-1, lb);
Tensor::index ind(this, c); Tensor::index ind(*this, c);
TL_RAISE_IF(*ind < 0 || *ind >= ncols(), TL_RAISE_IF(*ind < 0 || *ind >= ncols(),
"Internal error in slicing constructor of FGSTensor"); "Internal error in slicing constructor of FGSTensor");
copyColumn(t, *run, *ind); copyColumn(t, *run, *ind);
@ -245,13 +245,13 @@ FGSTensor::FGSTensor(const FFSTensor &t, const IntSequence &ss,
// |FGSTensor| conversion from |GSSparseTensor| // |FGSTensor| conversion from |GSSparseTensor|
FGSTensor::FGSTensor(const GSSparseTensor &t) FGSTensor::FGSTensor(const GSSparseTensor &t)
: FTensor(along_col, t.getDims().getNVX(), t.nrows(), : FTensor(indor::along_col, t.getDims().getNVX(), t.nrows(),
t.getDims().calcFoldMaxOffset(), t.dimen()), tdims(t.getDims()) t.getDims().calcFoldMaxOffset(), t.dimen()), tdims(t.getDims())
{ {
zeros(); zeros();
for (const auto & it : t.getMap()) for (const auto & it : t.getMap())
{ {
index ind(this, it.first); index ind(*this, it.first);
get(it.second.first, *ind) = it.second.second; get(it.second.first, *ind) = it.second.second;
} }
} }
@ -338,13 +338,13 @@ FGSTensor::contractAndAdd(int i, FGSTensor &out,
unfold data within the unfolded tensor. */ unfold data within the unfolded tensor. */
UGSTensor::UGSTensor(const FGSTensor &ft) UGSTensor::UGSTensor(const FGSTensor &ft)
: UTensor(along_col, ft.tdims.getNVX(), ft.nrows(), : UTensor(indor::along_col, ft.tdims.getNVX(), ft.nrows(),
ft.tdims.calcUnfoldMaxOffset(), ft.dimen()), ft.tdims.calcUnfoldMaxOffset(), ft.dimen()),
tdims(ft.tdims) tdims(ft.tdims)
{ {
for (index fi = ft.begin(); fi != ft.end(); ++fi) for (index fi = ft.begin(); fi != ft.end(); ++fi)
{ {
index ui(this, fi.getCoor()); index ui(*this, fi.getCoor());
copyColumn(ft, *fi, *ui); copyColumn(ft, *fi, *ui);
} }
unfoldData(); unfoldData();
@ -354,7 +354,7 @@ UGSTensor::UGSTensor(const FGSTensor &ft)
/* This makes a folded slice from the sparse tensor and unfolds it. */ /* This makes a folded slice from the sparse tensor and unfolds it. */
UGSTensor::UGSTensor(const FSSparseTensor &t, const IntSequence &ss, UGSTensor::UGSTensor(const FSSparseTensor &t, const IntSequence &ss,
const IntSequence &coor, const TensorDimens &td) const IntSequence &coor, const TensorDimens &td)
: UTensor(along_col, td.getNVX(), t.nrows(), : UTensor(indor::along_col, td.getNVX(), t.nrows(),
td.calcUnfoldMaxOffset(), td.dimen()), td.calcUnfoldMaxOffset(), td.dimen()),
tdims(td) tdims(td)
{ {
@ -364,7 +364,7 @@ UGSTensor::UGSTensor(const FSSparseTensor &t, const IntSequence &ss,
FGSTensor ft(t, ss, coor, td); FGSTensor ft(t, ss, coor, td);
for (index fi = ft.begin(); fi != ft.end(); ++fi) for (index fi = ft.begin(); fi != ft.end(); ++fi)
{ {
index ui(this, fi.getCoor()); index ui(*this, fi.getCoor());
copyColumn(ft, *fi, *ui); copyColumn(ft, *fi, *ui);
} }
unfoldData(); unfoldData();
@ -374,7 +374,7 @@ UGSTensor::UGSTensor(const FSSparseTensor &t, const IntSequence &ss,
/* This makes a folded slice from dense and unfolds it. */ /* This makes a folded slice from dense and unfolds it. */
UGSTensor::UGSTensor(const UFSTensor &t, const IntSequence &ss, UGSTensor::UGSTensor(const UFSTensor &t, const IntSequence &ss,
const IntSequence &coor, const TensorDimens &td) const IntSequence &coor, const TensorDimens &td)
: UTensor(along_col, td.getNVX(), t.nrows(), : UTensor(indor::along_col, td.getNVX(), t.nrows(),
td.calcUnfoldMaxOffset(), td.dimen()), td.calcUnfoldMaxOffset(), td.dimen()),
tdims(td) tdims(td)
{ {
@ -382,7 +382,7 @@ UGSTensor::UGSTensor(const UFSTensor &t, const IntSequence &ss,
FGSTensor ft(folded, ss, coor, td); FGSTensor ft(folded, ss, coor, td);
for (index fi = ft.begin(); fi != ft.end(); ++fi) for (index fi = ft.begin(); fi != ft.end(); ++fi)
{ {
index ui(this, fi.getCoor()); index ui(*this, fi.getCoor());
copyColumn(ft, *fi, *ui); copyColumn(ft, *fi, *ui);
} }
unfoldData(); unfoldData();
@ -450,7 +450,7 @@ UGSTensor::getFirstIndexOf(const index &in) const
vtmp.sort(); vtmp.sort();
last += tdims.getSym()[i]; last += tdims.getSym()[i];
} }
return index(this, v); return index(*this, v);
} }
/* Here is perfectly same code with the same semantics as in /* Here is perfectly same code with the same semantics as in

View File

@ -147,7 +147,7 @@ public:
from |FFSTensor| to |FGSTensor|. */ from |FFSTensor| to |FGSTensor|. */
FGSTensor(int r, const TensorDimens &td) FGSTensor(int r, const TensorDimens &td)
: FTensor(along_col, td.getNVX(), r, : FTensor(indor::along_col, td.getNVX(), r,
td.calcFoldMaxOffset(), td.dimen()), tdims(td) td.calcFoldMaxOffset(), td.dimen()), tdims(td)
{ {
} }
@ -216,7 +216,7 @@ public:
constructor allows for in-place conversion from |UFSTensor| to constructor allows for in-place conversion from |UFSTensor| to
|UGSTensor|. */ |UGSTensor|. */
UGSTensor(int r, const TensorDimens &td) UGSTensor(int r, const TensorDimens &td)
: UTensor(along_col, td.getNVX(), r, : UTensor(indor::along_col, td.getNVX(), r,
td.calcUnfoldMaxOffset(), td.dimen()), tdims(td) td.calcUnfoldMaxOffset(), td.dimen()), tdims(td)
{ {
} }

View File

@ -62,7 +62,7 @@ UNormalMoments::generateMoments(int maxdim, const TwoDMatrix &v)
{ {
IntSequence ind(kronv->dimen()); IntSequence ind(kronv->dimen());
per.apply(it.getCoor(), ind); per.apply(it.getCoor(), ind);
Tensor::index it2(mom, ind); Tensor::index it2(*mom, ind);
mom->get(*it2, 0) += kronv->get(*it, 0); mom->get(*it2, 0) += kronv->get(*it, 0);
} }
} }

View File

@ -70,54 +70,34 @@ Permutation::computeSortingMap(const IntSequence &s)
} }
PermutationSet::PermutationSet() PermutationSet::PermutationSet()
: pers(new const Permutation *[size])
{ {
pers[0] = new Permutation(1); pers.emplace_back(1);
} }
PermutationSet::PermutationSet(const PermutationSet &sp, int n) PermutationSet::PermutationSet(const PermutationSet &sp, int n)
: order(n), size(n*sp.size), : order(n), size(n*sp.size)
pers(new const Permutation *[size])
{ {
for (int i = 0; i < size; i++)
pers[i] = nullptr;
TL_RAISE_IF(n != sp.order+1, TL_RAISE_IF(n != sp.order+1,
"Wrong new order in PermutationSet constructor"); "Wrong new order in PermutationSet constructor");
int k = 0;
for (int i = 0; i < sp.size; i++) for (int i = 0; i < sp.size; i++)
{ for (int j = 0; j < order; j++)
for (int j = 0; j < order; j++, k++) pers.emplace_back(sp.pers[i], j);
{
pers[k] = new Permutation(*(sp.pers[i]), j);
}
}
} }
PermutationSet::~PermutationSet() std::vector<Permutation>
{
for (int i = 0; i < size; i++)
if (pers[i])
delete pers[i];
delete [] pers;
}
std::vector<const Permutation *>
PermutationSet::getPreserving(const IntSequence &s) const PermutationSet::getPreserving(const IntSequence &s) const
{ {
TL_RAISE_IF(s.size() != order, TL_RAISE_IF(s.size() != order,
"Wrong sequence length in PermutationSet::getPreserving"); "Wrong sequence length in PermutationSet::getPreserving");
std::vector<const Permutation *> res; std::vector<Permutation> res;
IntSequence tmp(s.size()); IntSequence tmp(s.size());
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
pers[i]->apply(s, tmp); pers[i].apply(s, tmp);
if (s == tmp) if (s == tmp)
{ res.push_back(pers[i]);
res.push_back(pers[i]);
}
} }
return res; return res;
@ -129,35 +109,25 @@ PermutationBundle::PermutationBundle(int nmax)
generateUpTo(nmax); generateUpTo(nmax);
} }
PermutationBundle::~PermutationBundle()
{
for (auto & i : bundle)
delete i;
}
const PermutationSet & const PermutationSet &
PermutationBundle::get(int n) const PermutationBundle::get(int n) const
{ {
if (n > (int) (bundle.size()) || n < 1) if (n > static_cast<int>(bundle.size()) || n < 1)
{ {
TL_RAISE("Permutation set not found in PermutationSet::get"); TL_RAISE("Permutation set not found in PermutationSet::get");
return *(bundle[0]); return bundle[0];
} }
else else
{ return bundle[n-1];
return *(bundle[n-1]);
}
} }
void void
PermutationBundle::generateUpTo(int nmax) PermutationBundle::generateUpTo(int nmax)
{ {
if (bundle.size() == 0) if (bundle.size() == 0)
bundle.push_back(new PermutationSet()); bundle.emplace_back();
int curmax = bundle.size(); int curmax = bundle.size();
for (int n = curmax+1; n <= nmax; n++) for (int n = curmax+1; n <= nmax; n++)
{ bundle.emplace_back(bundle.back(), n);
bundle.push_back(new PermutationSet(*(bundle.back()), n));
}
} }

View File

@ -76,9 +76,8 @@ public:
{ {
computeSortingMap(s); computeSortingMap(s);
}; };
Permutation(const Permutation &p) Permutation(const Permutation &) = default;
Permutation(Permutation &&) = default;
= default;
Permutation(const Permutation &p1, const Permutation &p2) Permutation(const Permutation &p1, const Permutation &p2)
: permap(p2.permap) : permap(p2.permap)
{ {
@ -88,9 +87,8 @@ public:
: permap(p.size(), p.permap, i) : permap(p.size(), p.permap, i)
{ {
} }
Permutation & Permutation &operator=(const Permutation &) = default;
operator=(const Permutation &p) Permutation &operator=(Permutation &&) = default;
= default;
bool bool
operator==(const Permutation &p) operator==(const Permutation &p)
{ {
@ -129,7 +127,7 @@ protected:
element sets. The second constructor constructs a new permutation set element sets. The second constructor constructs a new permutation set
over $n$ from all permutations over $n-1$. The parameter $n$ need not over $n$ from all permutations over $n-1$. The parameter $n$ need not
to be provided, but it serves to distinguish the constructor from copy to be provided, but it serves to distinguish the constructor from copy
constructor, which is not provided. constructor.
The method |getPreserving| returns a factor subgroup of permutations, The method |getPreserving| returns a factor subgroup of permutations,
which are invariants with respect to the given sequence. This are all which are invariants with respect to the given sequence. This are all
@ -140,11 +138,11 @@ class PermutationSet
{ {
int order{1}; int order{1};
int size{1}; int size{1};
const Permutation **const pers; std::vector<Permutation> pers;
public: public:
PermutationSet(); PermutationSet();
PermutationSet(const PermutationSet &ps, int n); PermutationSet(const PermutationSet &ps, int n);
~PermutationSet(); ~PermutationSet() = default;
int int
getNum() const getNum() const
{ {
@ -153,9 +151,9 @@ public:
const Permutation & const Permutation &
get(int i) const get(int i) const
{ {
return *(pers[i]); return pers[i];
} }
std::vector<const Permutation *> getPreserving(const IntSequence &s) const; std::vector<Permutation> getPreserving(const IntSequence &s) const;
}; };
/* The permutation bundle encapsulates all permutations sets up to some /* The permutation bundle encapsulates all permutations sets up to some
@ -163,10 +161,10 @@ public:
class PermutationBundle class PermutationBundle
{ {
std::vector<PermutationSet *> bundle; std::vector<PermutationSet> bundle;
public: public:
PermutationBundle(int nmax); PermutationBundle(int nmax);
~PermutationBundle(); ~PermutationBundle() = default;
const PermutationSet&get(int n) const; const PermutationSet&get(int n) const;
void generateUpTo(int nmax); void generateUpTo(int nmax);
}; };

View File

@ -25,7 +25,7 @@ UPSTensor::decideFillMethod(const FSSparseTensor &t)
UPSTensor::UPSTensor(const FSSparseTensor &t, const IntSequence &ss, UPSTensor::UPSTensor(const FSSparseTensor &t, const IntSequence &ss,
const IntSequence &coor, const PerTensorDimens &ptd) const IntSequence &coor, const PerTensorDimens &ptd)
: UTensor(along_col, ptd.getNVX(), : UTensor(indor::along_col, ptd.getNVX(),
t.nrows(), ptd.calcUnfoldMaxOffset(), ptd.dimen()), t.nrows(), ptd.calcUnfoldMaxOffset(), ptd.dimen()),
tdims(ptd) tdims(ptd)
{ {
@ -84,7 +84,7 @@ UPSTensor::addTo(FGSTensor &out) const
{ {
IntSequence vtmp(dimen()); IntSequence vtmp(dimen());
tdims.getPer().apply(in.getCoor(), vtmp); tdims.getPer().apply(in.getCoor(), vtmp);
index tin(this, vtmp); index tin(*this, vtmp);
out.addColumn(*this, *tin, *in); out.addColumn(*this, *tin, *in);
} }
} }
@ -127,7 +127,7 @@ UPSTensor::addTo(UGSTensor &out) const
// permute |outrun| // permute |outrun|
IntSequence perrun(out.dimen()); IntSequence perrun(out.dimen());
tdims.getPer().apply(outrun, perrun); tdims.getPer().apply(outrun, perrun);
index from(this, perrun); index from(*this, perrun);
// construct submatrices // construct submatrices
ConstTwoDMatrix subfrom(*this, *from, cols); ConstTwoDMatrix subfrom(*this, *from, cols);
TwoDMatrix subout(out, out_col, cols); TwoDMatrix subout(out, out_col, cols);
@ -215,7 +215,7 @@ UPSTensor::fillFromSparseTwo(const FSSparseTensor &t, const IntSequence &ss,
} }
const PermutationSet &pset = tls.pbundle->get(coor.size()); const PermutationSet &pset = tls.pbundle->get(coor.size());
std::vector<const Permutation *> pp = pset.getPreserving(coor); std::vector<Permutation> pp = pset.getPreserving(coor);
Permutation unsort(coor); Permutation unsort(coor);
zeros(); zeros();
@ -231,8 +231,8 @@ UPSTensor::fillFromSparseTwo(const FSSparseTensor &t, const IntSequence &ss,
for (auto & i : pp) for (auto & i : pp)
{ {
IntSequence cp(coor.size()); IntSequence cp(coor.size());
i->apply(c, cp); i.apply(c, cp);
Tensor::index ind(this, cp); Tensor::index ind(*this, cp);
TL_RAISE_IF(*ind < 0 || *ind >= ncols(), TL_RAISE_IF(*ind < 0 || *ind >= ncols(),
"Internal error in slicing constructor of UPSTensor"); "Internal error in slicing constructor of UPSTensor");
get((*run).second.first, *ind) = (*run).second.second; get((*run).second.first, *ind) = (*run).second.second;
@ -345,7 +345,7 @@ FPSTensor::addTo(FGSTensor &out) const
{ {
IntSequence coor(dimen()); IntSequence coor(dimen());
tdims.getPer().apply(tar.getCoor(), coor); tdims.getPer().apply(tar.getCoor(), coor);
index src(this, coor); index src(*this, coor);
out.addColumn(*this, *src, *tar); out.addColumn(*this, *src, *tar);
} }
} }
@ -372,7 +372,7 @@ FPSTensor::addTo(FGSTensor &out) const
FPSTensor::FPSTensor(const TensorDimens &td, const Equivalence &e, const Permutation &p, FPSTensor::FPSTensor(const TensorDimens &td, const Equivalence &e, const Permutation &p,
const GSSparseTensor &a, const KronProdAll &kp) const GSSparseTensor &a, const KronProdAll &kp)
: FTensor(along_col, PerTensorDimens(td, Permutation(e, p)).getNVX(), : FTensor(indor::along_col, PerTensorDimens(td, Permutation(e, p)).getNVX(),
a.nrows(), kp.ncols(), td.dimen()), a.nrows(), kp.ncols(), td.dimen()),
tdims(td, e, p) tdims(td, e, p)
{ {

View File

@ -172,28 +172,28 @@ public:
|KronProdAllOptim|, which permutes the permuted equivalence classes. */ |KronProdAllOptim|, which permutes the permuted equivalence classes. */
UPSTensor(const TensorDimens &td, const Equivalence &e, UPSTensor(const TensorDimens &td, const Equivalence &e,
const ConstTwoDMatrix &a, const KronProdAll &kp) const ConstTwoDMatrix &a, const KronProdAll &kp)
: UTensor(along_col, PerTensorDimens(td, e).getNVX(), : UTensor(indor::along_col, PerTensorDimens(td, e).getNVX(),
a.nrows(), kp.ncols(), td.dimen()), tdims(td, e) a.nrows(), kp.ncols(), td.dimen()), tdims(td, e)
{ {
kp.mult(a, *this); kp.mult(a, *this);
} }
UPSTensor(const TensorDimens &td, const Equivalence &e, UPSTensor(const TensorDimens &td, const Equivalence &e,
const ConstTwoDMatrix &a, const KronProdAllOptim &kp) const ConstTwoDMatrix &a, const KronProdAllOptim &kp)
: UTensor(along_col, PerTensorDimens(td, Permutation(e, kp.getPer())).getNVX(), : UTensor(indor::along_col, PerTensorDimens(td, Permutation(e, kp.getPer())).getNVX(),
a.nrows(), kp.ncols(), td.dimen()), tdims(td, Permutation(e, kp.getPer())) a.nrows(), kp.ncols(), td.dimen()), tdims(td, Permutation(e, kp.getPer()))
{ {
kp.mult(a, *this); kp.mult(a, *this);
} }
UPSTensor(const TensorDimens &td, const Equivalence &e, const Permutation &p, UPSTensor(const TensorDimens &td, const Equivalence &e, const Permutation &p,
const ConstTwoDMatrix &a, const KronProdAll &kp) const ConstTwoDMatrix &a, const KronProdAll &kp)
: UTensor(along_col, PerTensorDimens(td, Permutation(e, p)).getNVX(), : UTensor(indor::along_col, PerTensorDimens(td, Permutation(e, p)).getNVX(),
a.nrows(), kp.ncols(), td.dimen()), tdims(td, Permutation(e, p)) a.nrows(), kp.ncols(), td.dimen()), tdims(td, Permutation(e, p))
{ {
kp.mult(a, *this); kp.mult(a, *this);
} }
UPSTensor(const TensorDimens &td, const Equivalence &e, const Permutation &p, UPSTensor(const TensorDimens &td, const Equivalence &e, const Permutation &p,
const ConstTwoDMatrix &a, const KronProdAllOptim &kp) const ConstTwoDMatrix &a, const KronProdAllOptim &kp)
: UTensor(along_col, PerTensorDimens(td, Permutation(e, Permutation(p, kp.getPer()))).getNVX(), : UTensor(indor::along_col, PerTensorDimens(td, Permutation(e, Permutation(p, kp.getPer()))).getNVX(),
a.nrows(), kp.ncols(), td.dimen()), tdims(td, Permutation(e, Permutation(p, kp.getPer()))) a.nrows(), kp.ncols(), td.dimen()), tdims(td, Permutation(e, Permutation(p, kp.getPer())))
{ {
kp.mult(a, *this); kp.mult(a, *this);
@ -334,28 +334,28 @@ public:
sparse tensor). */ sparse tensor). */
FPSTensor(const TensorDimens &td, const Equivalence &e, FPSTensor(const TensorDimens &td, const Equivalence &e,
const ConstTwoDMatrix &a, const KronProdAll &kp) const ConstTwoDMatrix &a, const KronProdAll &kp)
: FTensor(along_col, PerTensorDimens(td, e).getNVX(), : FTensor(indor::along_col, PerTensorDimens(td, e).getNVX(),
a.nrows(), kp.ncols(), td.dimen()), tdims(td, e) a.nrows(), kp.ncols(), td.dimen()), tdims(td, e)
{ {
kp.mult(a, *this); kp.mult(a, *this);
} }
FPSTensor(const TensorDimens &td, const Equivalence &e, FPSTensor(const TensorDimens &td, const Equivalence &e,
const ConstTwoDMatrix &a, const KronProdAllOptim &kp) const ConstTwoDMatrix &a, const KronProdAllOptim &kp)
: FTensor(along_col, PerTensorDimens(td, Permutation(e, kp.getPer())).getNVX(), : FTensor(indor::along_col, PerTensorDimens(td, Permutation(e, kp.getPer())).getNVX(),
a.nrows(), kp.ncols(), td.dimen()), tdims(td, e, kp.getPer()) a.nrows(), kp.ncols(), td.dimen()), tdims(td, e, kp.getPer())
{ {
kp.mult(a, *this); kp.mult(a, *this);
} }
FPSTensor(const TensorDimens &td, const Equivalence &e, const Permutation &p, FPSTensor(const TensorDimens &td, const Equivalence &e, const Permutation &p,
const ConstTwoDMatrix &a, const KronProdAll &kp) const ConstTwoDMatrix &a, const KronProdAll &kp)
: FTensor(along_col, PerTensorDimens(td, Permutation(e, p)).getNVX(), : FTensor(indor::along_col, PerTensorDimens(td, Permutation(e, p)).getNVX(),
a.nrows(), kp.ncols(), td.dimen()), tdims(td, e, p) a.nrows(), kp.ncols(), td.dimen()), tdims(td, e, p)
{ {
kp.mult(a, *this); kp.mult(a, *this);
} }
FPSTensor(const TensorDimens &td, const Equivalence &e, const Permutation &p, FPSTensor(const TensorDimens &td, const Equivalence &e, const Permutation &p,
const ConstTwoDMatrix &a, const KronProdAllOptim &kp) const ConstTwoDMatrix &a, const KronProdAllOptim &kp)
: FTensor(along_col, PerTensorDimens(td, Permutation(e, Permutation(p, kp.getPer()))).getNVX(), : FTensor(indor::along_col, PerTensorDimens(td, Permutation(e, Permutation(p, kp.getPer()))).getNVX(),
a.nrows(), kp.ncols(), td.dimen()), tdims(td, e, Permutation(p, kp.getPer())) a.nrows(), kp.ncols(), td.dimen()), tdims(td, e, Permutation(p, kp.getPer()))
{ {
kp.mult(a, *this); kp.mult(a, *this);

View File

@ -67,7 +67,7 @@ USubTensor::addKronColumn(int i, const std::vector<const FGSTensor *> &ts,
{ {
IntSequence ind(pindex, lastdim, lastdim+t->dimen()); IntSequence ind(pindex, lastdim, lastdim+t->dimen());
lastdim += t->dimen(); lastdim += t->dimen();
index in(t, ind); index in(*t, ind);
tmpcols.push_back(t->getCol(*in)); tmpcols.push_back(t->getCol(*in));
} }

View File

@ -79,7 +79,7 @@ IrregTensorHeader::calcMaxOffset() const
multiply all columns of the header. */ multiply all columns of the header. */
IrregTensor::IrregTensor(const IrregTensorHeader &h) IrregTensor::IrregTensor(const IrregTensorHeader &h)
: Tensor(along_row, IntSequence(h.dimen(), 0), h.end_seq, : Tensor(indor::along_row, IntSequence(h.dimen(), 0), h.end_seq,
h.calcMaxOffset(), 1, h.dimen()), h.calcMaxOffset(), 1, h.dimen()),
header(h) header(h)
{ {
@ -110,7 +110,7 @@ IrregTensor::addTo(FRSingleTensor &out) const
{ {
IntSequence tmp(it.getCoor()); IntSequence tmp(it.getCoor());
tmp.sort(); tmp.sort();
Tensor::index ind(&out, tmp); Tensor::index ind(out, tmp);
out.get(*ind, 0) += get(*it, 0); out.get(*ind, 0) += get(*it, 0);
} }
} }

View File

@ -10,7 +10,7 @@
rows in the unfolded tensor |ut|, make an index of the folded tensor rows in the unfolded tensor |ut|, make an index of the folded tensor
by sorting the coordinates, and add the row. */ by sorting the coordinates, and add the row. */
FRTensor::FRTensor(const URTensor &ut) FRTensor::FRTensor(const URTensor &ut)
: FTensor(along_row, IntSequence(ut.dimen(), ut.nvar()), : FTensor(indor::along_row, IntSequence(ut.dimen(), ut.nvar()),
FFSTensor::calcMaxOffset(ut.nvar(), ut.dimen()), ut.ncols(), FFSTensor::calcMaxOffset(ut.nvar(), ut.dimen()), ut.ncols(),
ut.dimen()), ut.dimen()),
nv(ut.nvar()) nv(ut.nvar())
@ -20,7 +20,7 @@ FRTensor::FRTensor(const URTensor &ut)
{ {
IntSequence vtmp(in.getCoor()); IntSequence vtmp(in.getCoor());
vtmp.sort(); vtmp.sort();
index tar(this, vtmp); index tar(*this, vtmp);
addRow(ut, *in, *tar); addRow(ut, *in, *tar);
} }
} }
@ -62,7 +62,7 @@ FRTensor::decrement(IntSequence &v) const
(duplicates) zero. In this way, if the unfolded tensor is folded back, (duplicates) zero. In this way, if the unfolded tensor is folded back,
we should get the same data. */ we should get the same data. */
URTensor::URTensor(const FRTensor &ft) URTensor::URTensor(const FRTensor &ft)
: UTensor(along_row, IntSequence(ft.dimen(), ft.nvar()), : UTensor(indor::along_row, IntSequence(ft.dimen(), ft.nvar()),
UFSTensor::calcMaxOffset(ft.nvar(), ft.dimen()), ft.ncols(), UFSTensor::calcMaxOffset(ft.nvar(), ft.dimen()), ft.ncols(),
ft.dimen()), ft.dimen()),
nv(ft.nvar()) nv(ft.nvar())
@ -70,7 +70,7 @@ URTensor::URTensor(const FRTensor &ft)
zeros(); zeros();
for (index src = ft.begin(); src != ft.end(); ++src) for (index src = ft.begin(); src != ft.end(); ++src)
{ {
index in(this, src.getCoor()); index in(*this, src.getCoor());
copyRow(ft, *src, *in); copyRow(ft, *src, *in);
} }
} }
@ -181,7 +181,7 @@ FRSingleTensor::FRSingleTensor(const URSingleTensor &ut)
{ {
IntSequence vtmp(in.getCoor()); IntSequence vtmp(in.getCoor());
vtmp.sort(); vtmp.sort();
index tar(this, vtmp); index tar(*this, vtmp);
get(*tar, 0) += ut.get(*in, 0); get(*tar, 0) += ut.get(*in, 0);
} }
} }

View File

@ -48,7 +48,7 @@ class URTensor : public UTensor
int nv; int nv;
public: public:
URTensor(int c, int nvar, int d) URTensor(int c, int nvar, int d)
: UTensor(along_row, IntSequence(d, nvar), : UTensor(indor::along_row, IntSequence(d, nvar),
UFSTensor::calcMaxOffset(nvar, d), c, d), nv(nvar) UFSTensor::calcMaxOffset(nvar, d), c, d), nv(nvar)
{ {
} }
@ -84,7 +84,7 @@ class FRTensor : public FTensor
int nv; int nv;
public: public:
FRTensor(int c, int nvar, int d) FRTensor(int c, int nvar, int d)
: FTensor(along_row, IntSequence(d, nvar), : FTensor(indor::along_row, IntSequence(d, nvar),
FFSTensor::calcMaxOffset(nvar, d), c, d), nv(nvar) FFSTensor::calcMaxOffset(nvar, d), c, d), nv(nvar)
{ {
} }

View File

@ -247,7 +247,7 @@ public:
while (i < numStacks() && getType(i, s) == _Stype::matrix) while (i < numStacks() && getType(i, s) == _Stype::matrix)
{ {
const _Ttype *t = getMatrix(i, s); const _Ttype *t = getMatrix(i, s);
Tensor::index ind(t, coor); Tensor::index ind(*t, coor);
Vector subres(*res, stack_offsets[i], stack_sizes[i]); Vector subres(*res, stack_offsets[i], stack_sizes[i]);
subres = ConstGeneralMatrix(*t).getCol(*ind); subres = ConstGeneralMatrix(*t).getCol(*ind);
i++; i++;

View File

@ -49,96 +49,7 @@
#include "int_sequence.hh" #include "int_sequence.hh"
#include "twod_matrix.hh" #include "twod_matrix.hh"
/* The index represents $n$-tuple $\alpha_1\ldots\alpha_n$. Since its #include <iostream>
movement is dependent on the underlying tensor (with storage and
symmetry), we maintain a pointer to that tensor, we maintain the
$n$-tuple (or coordinates) as |IntSequence| and also we maintain the
offset number (column, or row) of the index in the tensor. The pointer
is const, since we do not need to change data through the index.
Here we require the |tensor| to implement |increment| and |decrement|
methods, which calculate following and preceding $n$-tuple. Also, we
need to calculate offset number from the given coordinates, so the
tensor must implement method |getOffset|. This method is used only in
construction of the index from the given coordinates. As the index is
created, the offset is automatically incremented, and decremented
together with index. The|getOffset| method can be relatively
computationally complex. This must be kept in mind. Also we generally
suppose that n-tuple of all zeros is the first offset (first columns
or row).
What follows is a definition of index class, the only
interesting point is |operator==| which decides only according to
offset, not according to the coordinates. This is useful since there
can be more than one of coordinate representations of past-the-end
index. */
template<class _Tptr>
class _index
{
using _Self = _index<_Tptr>;
_Tptr tensor;
int offset;
IntSequence coor;
public:
_index(_Tptr t, int n)
: tensor(t), offset(0), coor(n, 0)
{
}
_index(_Tptr t, const IntSequence &cr, int c)
: tensor(t), offset(c), coor(cr)
{
}
_index(_Tptr t, const IntSequence &cr)
: tensor(t), offset(tensor->getOffset(cr)), coor(cr)
{
}
_index(const _index &ind)
: tensor(ind.tensor), offset(ind.offset), coor(ind.coor)
{
}
const _Self &
operator=(const _Self &in)
{
tensor = in.tensor; offset = in.offset; coor = in.coor;
return *this;
}
_Self &
operator++()
{
tensor->increment(coor); offset++; return *this;
}
_Self &
operator--()
{
tensor->decrement(coor); offset--; return *this;
}
int
operator*() const
{
return offset;
}
bool
operator==(const _index &n) const
{
return offset == n.offset;
}
bool
operator!=(const _index &n) const
{
return offset != n.offset;
}
const IntSequence &
getCoor() const
{
return coor;
}
void
print() const
{
printf("%4d: ", offset); coor.print();
}
};
/* Here is the |Tensor| class, which is nothing else than a simple subclass /* Here is the |Tensor| class, which is nothing else than a simple subclass
of |TwoDMatrix|. The unique semantically new member is |dim| which is tensor of |TwoDMatrix|. The unique semantically new member is |dim| which is tensor
@ -161,8 +72,95 @@ public:
class Tensor : public TwoDMatrix class Tensor : public TwoDMatrix
{ {
public: public:
enum indor {along_row, along_col}; enum class indor {along_row, along_col};
using index = _index<const Tensor *>;
/* The index represents $n$-tuple $\alpha_1\ldots\alpha_n$. Since its
movement is dependent on the underlying tensor (with storage and
symmetry), we maintain a reference to that tensor, we maintain the
$n$-tuple (or coordinates) as |IntSequence| and also we maintain the
offset number (column, or row) of the index in the tensor. The reference
is const, since we do not need to change data through the index.
Here we require the |tensor| to implement |increment| and |decrement|
methods, which calculate following and preceding $n$-tuple. Also, we
need to calculate offset number from the given coordinates, so the
tensor must implement method |getOffset|. This method is used only in
construction of the index from the given coordinates. As the index is
created, the offset is automatically incremented, and decremented
together with index. The |getOffset| method can be relatively
computationally complex. This must be kept in mind. Also we generally
suppose that n-tuple of all zeros is the first offset (first columns
or row).
What follows is a definition of index class, the only
interesting point is |operator==| which decides only according to
offset, not according to the coordinates. This is useful since there
can be more than one of coordinate representations of past-the-end
index. */
class index
{
const Tensor &tensor;
int offset;
IntSequence coor;
public:
index(const Tensor &t, int n)
: tensor(t), offset(0), coor(n, 0)
{
}
index(const Tensor &t, const IntSequence &cr, int c)
: tensor(t), offset(c), coor(cr)
{
}
index(const Tensor &t, const IntSequence &cr)
: tensor(t), offset(tensor.getOffset(cr)), coor(cr)
{
}
index(const index &) = default;
index(index &&) = default;
index &operator=(const index &) = delete;
index &operator=(index &&) = delete;
index &
operator++()
{
tensor.increment(coor);
offset++;
return *this;
}
index &
operator--()
{
tensor.decrement(coor);
offset--;
return *this;
}
int
operator*() const
{
return offset;
}
bool
operator==(const index &n) const
{
return offset == n.offset;
}
bool
operator!=(const index &n) const
{
return offset != n.offset;
}
const IntSequence &
getCoor() const
{
return coor;
}
void
print() const
{
std::cout << offset << ": ";
coor.print();
}
};
protected: protected:
const index in_beg; const index in_beg;
const index in_end; const index in_end;
@ -170,16 +168,16 @@ protected:
public: public:
Tensor(indor io, const IntSequence &last, int r, int c, int d) Tensor(indor io, const IntSequence &last, int r, int c, int d)
: TwoDMatrix(r, c), : TwoDMatrix(r, c),
in_beg(this, d), in_beg(*this, d),
in_end(this, last, (io == along_row) ? r : c), in_end(*this, last, (io == indor::along_row) ? r : c),
dim(d) dim(d)
{ {
} }
Tensor(indor io, const IntSequence &first, const IntSequence &last, Tensor(indor io, const IntSequence &first, const IntSequence &last,
int r, int c, int d) int r, int c, int d)
: TwoDMatrix(r, c), : TwoDMatrix(r, c),
in_beg(this, first, 0), in_beg(*this, first, 0),
in_end(this, last, (io == along_row) ? r : c), in_end(*this, last, (io == indor::along_row) ? r : c),
dim(d) dim(d)
{ {
} }
@ -192,13 +190,17 @@ public:
} }
Tensor(const Tensor &t) Tensor(const Tensor &t)
: TwoDMatrix(t), : TwoDMatrix(t),
in_beg(this, t.in_beg.getCoor(), *(t.in_beg)), in_beg(*this, t.in_beg.getCoor(), *(t.in_beg)),
in_end(this, t.in_end.getCoor(), *(t.in_end)), in_end(*this, t.in_end.getCoor(), *(t.in_end)),
dim(t.dim) dim(t.dim)
{ {
} }
~Tensor() Tensor(Tensor &&) = default;
override = default; ~Tensor() override = default;
Tensor &operator=(const Tensor &) = delete;
Tensor &operator=(Tensor &&) = delete;
virtual void increment(IntSequence &v) const = 0; virtual void increment(IntSequence &v) const = 0;
virtual void decrement(IntSequence &v) const = 0; virtual void decrement(IntSequence &v) const = 0;
virtual int getOffset(const IntSequence &v) const = 0; virtual int getOffset(const IntSequence &v) const = 0;
@ -245,16 +247,17 @@ public:
: Tensor(io, last, r, c, d) : Tensor(io, last, r, c, d)
{ {
} }
UTensor(const UTensor &ut) UTensor(const UTensor &) = default;
UTensor(UTensor &&) = default;
= default;
UTensor(int first_row, int num, UTensor &t) UTensor(int first_row, int num, UTensor &t)
: Tensor(first_row, num, t) : Tensor(first_row, num, t)
{ {
} }
~UTensor() ~UTensor() override = default;
override = default; virtual FTensor &fold() const = 0;
virtual FTensor&fold() const = 0;
UTensor &operator=(const UTensor &) = delete;
UTensor &operator=(UTensor &&) = delete;
static void increment(IntSequence &v, int nv); static void increment(IntSequence &v, int nv);
static void decrement(IntSequence &v, int nv); static void decrement(IntSequence &v, int nv);
@ -280,22 +283,24 @@ public:
: Tensor(io, last, r, c, d) : Tensor(io, last, r, c, d)
{ {
} }
FTensor(const FTensor &ft) FTensor(const FTensor &) = default;
FTensor(FTensor &&) = default;
= default;
FTensor(int first_row, int num, FTensor &t) FTensor(int first_row, int num, FTensor &t)
: Tensor(first_row, num, t) : Tensor(first_row, num, t)
{ {
} }
~FTensor() ~FTensor() override = default;
override = default; virtual UTensor &unfold() const = 0;
virtual UTensor&unfold() const = 0;
FTensor &operator=(const FTensor &) = delete;
FTensor &operator=(FTensor &&) = delete;
static void decrement(IntSequence &v, int nv); static void decrement(IntSequence &v, int nv);
static int static int
getOffset(const IntSequence &v, int nv) getOffset(const IntSequence &v, int nv)
{ {
IntSequence vtmp(v); return getOffsetRecurse(vtmp, nv); IntSequence vtmp(v);
return getOffsetRecurse(vtmp, nv);
} }
private: private:
static int getOffsetRecurse(IntSequence &v, int nv); static int getOffsetRecurse(IntSequence &v, int nv);

View File

@ -3,6 +3,11 @@
#include "twod_matrix.hh" #include "twod_matrix.hh"
#include "tl_exception.hh" #include "tl_exception.hh"
#include <vector>
#include <fstream>
#include <iomanip>
#include <limits>
ConstTwoDMatrix::ConstTwoDMatrix(const TwoDMatrix &m) ConstTwoDMatrix::ConstTwoDMatrix(const TwoDMatrix &m)
: ConstGeneralMatrix(m) : ConstGeneralMatrix(m)
{ {
@ -29,23 +34,22 @@ ConstTwoDMatrix::ConstTwoDMatrix(int first_row, int num, const ConstTwoDMatrix &
} }
void void
ConstTwoDMatrix::writeMat(mat_t *fd, const char *vname) const ConstTwoDMatrix::writeMat(mat_t *fd, const std::string &vname) const
{ {
size_t dims[2]; size_t dims[2];
dims[0] = nrows(); dims[0] = nrows();
dims[1] = ncols(); dims[1] = ncols();
auto *data = new double[nrows()*ncols()]; std::vector<double> data(nrows()*ncols());
for (int j = 0; j < ncols(); j++) for (int j = 0; j < ncols(); j++)
for (int i = 0; i < nrows(); i++) for (int i = 0; i < nrows(); i++)
data[j*nrows()+i] = get(i, j); data[j*nrows()+i] = get(i, j);
matvar_t *v = Mat_VarCreate(vname, MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, data, 0); matvar_t *v = Mat_VarCreate(vname.c_str(), MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, data.data(), 0);
Mat_VarWrite(fd, v, MAT_COMPRESSION_NONE); Mat_VarWrite(fd, v, MAT_COMPRESSION_NONE);
Mat_VarFree(v); Mat_VarFree(v);
delete[] data;
} }
TwoDMatrix & TwoDMatrix &
@ -94,18 +98,19 @@ TwoDMatrix::addColumn(double d, const ConstTwoDMatrix &m, int from, int to)
} }
void void
TwoDMatrix::save(const char *fname) const TwoDMatrix::save(const std::string &fname) const
{ {
FILE *fd; std::ofstream fd{fname, std::ios::out | std::ios::trunc};
if (nullptr == (fd = fopen(fname, "w"))) if (fd.fail())
{ TL_RAISE("Cannot open file for writing in TwoDMatrix::save");
TL_RAISE("Cannot open file for writing in TwoDMatrix::save");
} fd << std::setprecision(std::numeric_limits<double>::digits10 + 1);
for (int row = 0; row < nrows(); row++) for (int row = 0; row < nrows(); row++)
{ {
for (int col = 0; col < ncols(); col++) for (int col = 0; col < ncols(); col++)
fprintf(fd, " %20.10g", get(row, col)); fd << ' ' << get(row, col);
fprintf(fd, "\n"); fd << '\n';
} }
fclose(fd); fd.close();
} }

View File

@ -17,8 +17,9 @@
#include "GeneralMatrix.hh" #include "GeneralMatrix.hh"
#include <cstdio>
#include <matio.h> #include <matio.h>
#include <string>
#include <utility> #include <utility>
class TwoDMatrix; class TwoDMatrix;
@ -46,8 +47,7 @@ public:
: ConstGeneralMatrix(m, first_row, first_col, rows, cols) : ConstGeneralMatrix(m, first_row, first_col, rows, cols)
{ {
} }
~ConstTwoDMatrix() ~ConstTwoDMatrix() override = default;
override = default;
ConstTwoDMatrix &operator=(const ConstTwoDMatrix &v) = delete; ConstTwoDMatrix &operator=(const ConstTwoDMatrix &v) = delete;
ConstTwoDMatrix &operator=(ConstTwoDMatrix &&v) = delete; ConstTwoDMatrix &operator=(ConstTwoDMatrix &&v) = delete;
@ -62,7 +62,7 @@ public:
{ {
return numCols(); return numCols();
} }
void writeMat(mat_t *fd, const char *vname) const; void writeMat(mat_t *fd, const std::string &vname) const;
}; };
/* Here we do the same as for |ConstTwoDMatrix| plus define /* Here we do the same as for |ConstTwoDMatrix| plus define
@ -192,9 +192,9 @@ public:
addColumn(d, ConstTwoDMatrix(m), from, to); addColumn(d, ConstTwoDMatrix(m), from, to);
} }
void save(const char *fname) const; void save(const std::string &fname) const;
void void
writeMat(mat_t *fd, const char *vname) const writeMat(mat_t *fd, const std::string &vname) const
{ {
ConstTwoDMatrix(*this).writeMat(fd, vname); ConstTwoDMatrix(*this).writeMat(fd, vname);
} }

View File

@ -181,7 +181,7 @@ TestRunnable::index_offset(const Symmetry &s, const IntSequence &nvs)
for (typename _Ttype::index run = dummy.begin(); for (typename _Ttype::index run = dummy.begin();
run != dummy.end(); ++run, nincr++) run != dummy.end(); ++run, nincr++)
{ {
typename _Ttype::index run2(&dummy, run.getCoor()); typename _Ttype::index run2(dummy, run.getCoor());
if (!(run == run2)) if (!(run == run2))
fails++; fails++;
} }