Dynare++ tensor library: various simplifications/modernizations

parent d9f03452
Pipeline #799 failed with stages
in 66 minutes and 56 seconds
......@@ -4,7 +4,7 @@
#include "permutation.hh"
#include "tl_exception.hh"
#include <cstring>
#include <iostream>
int
OrdSequence::operator[](int i) const
......@@ -93,12 +93,12 @@ OrdSequence::average() const
/* Debug print. */
void
OrdSequence::print(const char *prefix) const
OrdSequence::print(const std::string &prefix) const
{
printf("%s", prefix);
std::cout << prefix;
for (int i : data)
printf("%d ", i);
printf("\n");
std::cout << i << ' ';
std::cout << '\n';
}
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)
{
OrdSequence s;
......@@ -121,12 +121,7 @@ Equivalence::Equivalence(int num, const char *dummy)
classes.push_back(s);
}
/* Copy constructors. The second also glues a given couple. */
Equivalence::Equivalence(const Equivalence &e)
= default;
/* Copy constructor that also glues a given couple. */
Equivalence::Equivalence(const Equivalence &e, int i1, int i2)
: 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
Equivalence::operator==(const Equivalence &e) const
{
......@@ -173,7 +159,7 @@ Equivalence::findHaving(int i) const
auto si = classes.begin();
while (si != classes.end())
{
if ((*si).has(i))
if (si->has(i))
return si;
++si;
}
......@@ -188,7 +174,7 @@ Equivalence::findHaving(int i)
auto si = classes.begin();
while (si != classes.end())
{
if ((*si).has(i))
if (si->has(i))
return si;
++si;
}
......@@ -251,7 +237,7 @@ Equivalence::trace(IntSequence &out, int num) const
int i = 0;
int nc = 0;
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(),
"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++)
{
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];
}
}
/* Debug print. */
void
Equivalence::print(const char *prefix) const
Equivalence::print(const std::string &prefix) const
{
int i = 0;
for (auto it = classes.begin();
it != classes.end();
++it, i++)
{
printf("%sclass %d: ", prefix, i);
(*it).print("");
std::cout << prefix << "class " << i << ": ";
it->print("");
}
}
......@@ -310,8 +296,7 @@ Equivalence::print(const char *prefix) const
(since it is constructed by gluing attempts). */
EquivalenceSet::EquivalenceSet(int num)
: n(num),
equis()
: n(num)
{
std::list<Equivalence> added;
Equivalence first(n);
......@@ -323,10 +308,7 @@ EquivalenceSet::EquivalenceSet(int num)
added.pop_front();
}
if (n > 1)
{
Equivalence last(n, "");
equis.push_back(last);
}
equis.emplace_back(n, "");
}
/* This method is used in |addParents| and returns |true| if the object
......@@ -371,25 +353,23 @@ EquivalenceSet::addParents(const Equivalence &e,
if (!has(ns))
{
added.push_back(ns);
equis.push_back(ns);
equis.push_back(std::move(ns));
}
}
}
/* Debug print. */
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;
for (auto it = equis.begin();
it != equis.end();
++it, i++)
{
printf("%sequivalence %d:(classes %d)\n", prefix, i, (*it).numClasses());
(*it).print(tmp);
std::cout << prefix << "equivalence " << i << ":(classes "
<< it->numClasses() << ")\n";
it->print(prefix + " ");
}
}
......@@ -404,15 +384,13 @@ EquivalenceBundle::EquivalenceBundle(int nmax)
const EquivalenceSet &
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");
return bundle[0];
}
else
{
return bundle[n-1];
}
return bundle[n-1];
}
/* Get |curmax| which is a maximum size in the bundle, and generate for
......
......@@ -43,6 +43,7 @@
#include <vector>
#include <list>
#include <string>
/* Here is the abstraction for an equivalence class. We implement it as
|vector<int>|. We have a constructor for empty class, copy
......@@ -58,11 +59,10 @@ public:
OrdSequence() : data()
{
}
OrdSequence(const OrdSequence &s)
= default;
OrdSequence &
operator=(const OrdSequence &s)
= default;
OrdSequence(const OrdSequence &) = default;
OrdSequence(OrdSequence &&) = default;
OrdSequence &operator=(const OrdSequence &) = default;
OrdSequence &operator=(OrdSequence &&) = default;
bool operator==(const OrdSequence &s) const;
int operator[](int i) const;
bool operator<(const OrdSequence &s) const;
......@@ -79,7 +79,7 @@ public:
void add(int i);
void add(const OrdSequence &s);
bool has(int i) const;
void print(const char *prefix) const;
void print(const std::string &prefix) const;
private:
double average() const;
};
......@@ -107,11 +107,13 @@ public:
The third is the copy constructor. And the fourth is the copy
constructor plus gluing |i1| and |i2| in one class. */
Equivalence(int num);
Equivalence(int num, const char *dummy);
Equivalence(const Equivalence &e);
Equivalence(int num, const std::string &dummy);
Equivalence(const Equivalence &) = default;
Equivalence(Equivalence &&) = default;
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
......@@ -135,7 +137,7 @@ public:
trace(out, numClasses());
}
void trace(IntSequence &out, const Permutation &per) const;
void print(const char *prefix) const;
void print(const std::string &prefix) const;
seqit
begin()
{
......@@ -185,7 +187,7 @@ class EquivalenceSet
public:
using const_iterator = std::list<Equivalence>::const_iterator;
EquivalenceSet(int num);
void print(const char *prefix) const;
void print(const std::string &prefix) const;
const_iterator
begin() const
{
......@@ -214,7 +216,7 @@ class EquivalenceBundle
public:
EquivalenceBundle(int nmax);
~EquivalenceBundle() = default;
const EquivalenceSet&get(int n) const;
const EquivalenceSet &get(int n) const;
void generateUpTo(int nmax);
};
......
......@@ -16,7 +16,7 @@
by an appropriate item of |x| and added to the column of $[g]$ tensor. */
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),
nv(t.nvar())
{
......@@ -32,7 +32,7 @@ FFSTensor::FFSTensor(const FFSTensor &t, const ConstVector &x)
for (int i = 0; i < nvar(); i++)
{
IntSequence from_ind(i, to.getCoor());
Tensor::index from(&t, from_ind);
Tensor::index from(t, from_ind);
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
tensor and write to the dense what is found. */
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()),
nv(t.nvar())
{
zeros();
for (const auto & it : t.getMap())
{
index ind(this, it.first);
index ind(*this, it.first);
get(it.second.first, *ind) = it.second.second;
}
}
......@@ -73,13 +73,13 @@ FFSTensor::FFSTensor(const FSSparseTensor &t)
copy the column. */
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()),
nv(ut.nvar())
{
for (index in = begin(); in != end(); ++in)
{
index src(&ut, in.getCoor());
index src(ut, in.getCoor());
copyColumn(ut, *src, *in);
}
}
......@@ -156,7 +156,7 @@ FFSTensor::addSubTensor(const FGSTensor &t)
IntSequence c(ind.getCoor());
c.add(1, shift);
c.sort();
Tensor::index tar(this, c);
Tensor::index tar(*this, c);
addColumn(t, *ind, *tar);
}
}
......@@ -167,7 +167,7 @@ FFSTensor::addSubTensor(const FGSTensor &t)
regularity of the unfolded tensor. */
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),
nv(t.nvar())
{
......@@ -190,13 +190,13 @@ UFSTensor::UFSTensor(const UFSTensor &t, const ConstVector &x)
columns of folded tensor, and then call |unfoldData()|. */
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()),
nv(ft.nvar())
{
for (index src = ft.begin(); src != ft.end(); ++src)
{
index in(this, src.getCoor());
index in(*this, src.getCoor());
copyColumn(ft, *src, *in);
}
unfoldData();
......@@ -266,7 +266,7 @@ UFSTensor::addSubTensor(const UGSTensor &t)
c.add(-1, shift);
if (c.isPositive() && c.less(t.getDims().getNVX()))
{
Tensor::index from(&t, c);
Tensor::index from(t, c);
addColumn(t, *from, *tar);
}
}
......@@ -283,7 +283,7 @@ UFSTensor::unfoldData()
{
IntSequence v(in.getCoor());
v.sort();
index tmp(this, v);
index tmp(*this, v);
copyColumn(*tmp, *in);
}
}
......@@ -52,7 +52,7 @@ public:
The fifth constructs a subtensor of selected rows. */
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)
{
}
......@@ -97,7 +97,7 @@ class UFSTensor : public UTensor
int nv;
public:
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)
{
}
......
......@@ -138,13 +138,13 @@ TensorDimens::decrement(IntSequence &v) const
/* Here we go through columns of folded, calculate column of unfolded,
and copy data. */
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()),
tdims(ut.tdims)
{
for (index ti = begin(); ti != end(); ++ti)
{
index ui(&ut, ti.getCoor());
index ui(ut, ti.getCoor());
copyColumn(ut, *ui, *ti);
}
}
......@@ -160,7 +160,7 @@ FGSTensor::FGSTensor(const UGSTensor &ut)
obtain coordinates in the |this| tensor and we copy the item. */
FGSTensor::FGSTensor(const FSSparseTensor &t, const IntSequence &ss,
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()),
tdims(td)
{
......@@ -192,7 +192,7 @@ FGSTensor::FGSTensor(const FSSparseTensor &t, const IntSequence &ss,
{
IntSequence c((*run).first);
c.add(-1, lb);
Tensor::index ind(this, c);
Tensor::index ind(*this, c);
TL_RAISE_IF(*ind < 0 || *ind >= ncols(),
"Internal error in slicing constructor of FGSTensor");
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|@>|. */
FGSTensor::FGSTensor(const FFSTensor &t, const IntSequence &ss,
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()),
tdims(td)
{
......@@ -226,8 +226,8 @@ FGSTensor::FGSTensor(const FFSTensor &t, const IntSequence &ss,
}
zeros();
Tensor::index lbi(&t, lb);
Tensor::index ubi(&t, ub);
Tensor::index lbi(t, lb);
Tensor::index ubi(t, ub);
++ubi;
for (Tensor::index run = lbi; run != ubi; ++run)
{
......@@ -235,7 +235,7 @@ FGSTensor::FGSTensor(const FFSTensor &t, const IntSequence &ss,
{
IntSequence c(run.getCoor());
c.add(-1, lb);
Tensor::index ind(this, c);
Tensor::index ind(*this, c);
TL_RAISE_IF(*ind < 0 || *ind >= ncols(),
"Internal error in slicing constructor of FGSTensor");
copyColumn(t, *run, *ind);
......@@ -245,13 +245,13 @@ FGSTensor::FGSTensor(const FFSTensor &t, const IntSequence &ss,
// |FGSTensor| conversion from |GSSparseTensor|
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())
{
zeros();
for (const auto & it : t.getMap())
{
index ind(this, it.first);
index ind(*this, it.first);
get(it.second.first, *ind) = it.second.second;
}
}
......@@ -338,13 +338,13 @@ FGSTensor::contractAndAdd(int i, FGSTensor &out,
unfold data within the unfolded tensor. */
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()),
tdims(ft.tdims)
{
for (index fi = ft.begin(); fi != ft.end(); ++fi)
{
index ui(this, fi.getCoor());
index ui(*this, fi.getCoor());
copyColumn(ft, *fi, *ui);
}
unfoldData();
......@@ -354,7 +354,7 @@ UGSTensor::UGSTensor(const FGSTensor &ft)
/* This makes a folded slice from the sparse tensor and unfolds it. */
UGSTensor::UGSTensor(const FSSparseTensor &t, const IntSequence &ss,
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()),
tdims(td)
{
......@@ -364,7 +364,7 @@ UGSTensor::UGSTensor(const FSSparseTensor &t, const IntSequence &ss,
FGSTensor ft(t, ss, coor, td);
for (index fi = ft.begin(); fi != ft.end(); ++fi)
{
index ui(this, fi.getCoor());
index ui(*this, fi.getCoor());
copyColumn(ft, *fi, *ui);
}
unfoldData();
......@@ -374,7 +374,7 @@ UGSTensor::UGSTensor(const FSSparseTensor &t, const IntSequence &ss,
/* This makes a folded slice from dense and unfolds it. */
UGSTensor::UGSTensor(const UFSTensor &t, const IntSequence &ss,
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()),
tdims(td)
{
......@@ -382,7 +382,7 @@ UGSTensor::UGSTensor(const UFSTensor &t, const IntSequence &ss,
FGSTensor ft(folded, ss, coor, td);
for (index fi = ft.begin(); fi != ft.end(); ++fi)
{
index ui(this, fi.getCoor());
index ui(*this, fi.getCoor());
copyColumn(ft, *fi, *ui);
}
unfoldData();
......@@ -450,7 +450,7 @@ UGSTensor::getFirstIndexOf(const index &in) const
vtmp.sort();
last += tdims.getSym()[i];
}
return index(this, v);
return index(*this, v);
}
/* Here is perfectly same code with the same semantics as in
......
......@@ -147,7 +147,7 @@ public:
from |FFSTensor| to |FGSTensor|. */
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)
{
}
......@@ -216,7 +216,7 @@ public:
constructor allows for in-place conversion from |UFSTensor| to
|UGSTensor|. */
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)
{
}
......
......@@ -62,7 +62,7 @@ UNormalMoments::generateMoments(int maxdim, const TwoDMatrix &v)
{
IntSequence ind(kronv->dimen());
per.apply(it.getCoor(), ind);
Tensor::index it2(mom, ind);
Tensor::index it2(*mom, ind);
mom->get(*it2, 0) += kronv->get(*it, 0);
}
}
......
......@@ -70,54 +70,34 @@ Permutation::computeSortingMap(const IntSequence &s)
}
PermutationSet::PermutationSet()
: pers(new const Permutation *[size])
{
pers[0] = new Permutation(1);
pers.emplace_back(1);
}
PermutationSet::PermutationSet(const PermutationSet &sp, int n)
: order(n), size(n*sp.size),
pers(new const Permutation *[size])
: order(n), size(n*sp.size)
{
for (int i = 0; i < size; i++)
pers[i] = nullptr;
TL_RAISE_IF(n != sp.order+1,
"Wrong new order in PermutationSet constructor");
int k = 0;
for (int i = 0; i < sp.size; i++)
{
for (int j = 0; j < order; j++, k++)
{
pers[k] = new Permutation(*(sp.pers[i]), j);
}
}
}
PermutationSet::~PermutationSet()
{
for (int i = 0; i < size; i++)
if (pers[i])
delete pers[i];
delete [] pers;
for (int j = 0; j < order; j++)
pers.emplace_back(sp.pers[i], j);
}
std::vector<const Permutation *>
std::vector<Permutation>
PermutationSet::getPreserving(const IntSequence &s) const
{
TL_RAISE_IF(s.size() != order,
"Wrong sequence length in PermutationSet::getPreserving");
std::vector<const Permutation *> res;
std::vector<Permutation> res;
IntSequence tmp(s.size());
for (int i = 0; i < size; i++)
{
pers[i]->apply(s, tmp);
pers[i].apply(s, tmp);
if (s == tmp)
{
res.push_back(pers[i]);
}
res.push_back(pers[i]);
}
return res;
......@@ -129,35 +109,25 @@ PermutationBundle::PermutationBundle(int nmax)
generateUpTo(nmax);
}
PermutationBundle::~PermutationBundle()
{
for (auto & i : bundle)
delete i;
}
const PermutationSet &
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");
return *(bundle[0]);
return bundle[0];
}
else
{
return *(bundle[n-1]);
}
return bundle[n-1];
}
void
PermutationBundle::generateUpTo(int nmax)
{
if (bundle.size() == 0)
bundle.push_back(new PermutationSet());
bundle.emplace_back();
int curmax = bundle.size();
for (int n = curmax+1; n <= nmax; n++)
{
bundle.push_back(new PermutationSet(*(bundle.back()), n));
}
bundle.emplace_back(bundle.back(), n);
}
......@@ -76,9 +76,8 @@ public:
{
computeSortingMap(s);
};
Permutation(const Permutation &p)
= default;
Permutation(const Permutation &) = default;
Permutation(Permutation &&) = default;
Permutation(const Permutation &p1, const Permutation &p2)
: permap(p2.permap)
{
......@@ -88,9 +87,8 @@ public:
: permap(p.size(), p.permap, i)
{
}
Permutation &
operator=(const Permutation &p)
= default;
Permutation &operator=(const Permutation &) = default;
Permutation &operator=(Permutation &&) = default;
bool
operator==(const Permutation &p)
{
......@@ -129,7 +127,7 @@ protected:
element sets. The second constructor constructs a new permutation set
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
constructor, which is not provided.
constructor.
The method |getPreserving| returns a factor subgroup of permutations,
which are invariants with respect to the given sequence. This are all
......@@ -140,11 +138,11 @@ class PermutationSet
{
int order{1};
int size{1};
const Permutation **const pers;
std::vector<Permutation> pers;
public:
PermutationSet();
PermutationSet(const PermutationSet &ps, int n);
~PermutationSet();
~PermutationSet() = default;
int
getNum() const
{
......@@ -153,9 +151,9 @@ public:
const Permutation &
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
......@@ -163,10 +161,10 @@ public:
class PermutationBundle
{
std::vector<PermutationSet *> bundle;
std::vector<PermutationSet> bundle;
public:
PermutationBundle(int nmax);
~PermutationBundle();
~PermutationBundle() = default;
const PermutationSet&get(int n) const;
void generateUpTo(int nmax);
};
......
......@@ -25,7 +25,7 @@ UPSTensor::decideFillMethod(const FSSparseTensor &t)
UPSTensor::UPSTensor(const FSSparseTensor &t, const IntSequence &ss,