MultiDimVector now contains an iterator, is a template and automatically allocates the right space

This commit is contained in:
David Holzmüller 2019-04-11 17:51:54 +02:00
parent 52b0077922
commit 7d02f0213a
3 changed files with 40 additions and 34 deletions

View File

@ -44,11 +44,20 @@ inline std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
return os; return os;
} }
template <typename It>
class MultiDimVector { class MultiDimVector {
It it;
public: public:
// put the first dimension into an outer vector for processing reasons // put the first dimension into an outer vector for processing reasons
std::vector<std::vector<double>> data; std::vector<std::vector<double>> data;
MultiDimVector(size_t n) : data(n){};
MultiDimVector(It it) : it(it), data(it.firstIndexBound()) {
auto sizes = it.numValuesPerFirstIndex();
for (size_t i = 0; i < sizes.size(); ++i) {
data[i].resize(sizes[i]);
}
};
void swap(MultiDimVector &other) { data.swap(other.data); } void swap(MultiDimVector &other) { data.swap(other.data); }
@ -57,23 +66,21 @@ class MultiDimVector {
data[dim].clear(); data[dim].clear();
} }
} }
It getJumpIterator() const { return it; }
}; };
template <typename It> template <typename It>
void multiply_lower_triangular_inplace(It it, std::vector<boost::numeric::ublas::matrix<double>> L, void multiply_lower_triangular_inplace(std::vector<boost::numeric::ublas::matrix<double>> L,
MultiDimVector &v) { MultiDimVector<It> &v) {
// the multiplication is based on a cyclic permutation of the indices: the last index of v becomes // the multiplication is based on a cyclic permutation of the indices: the last index of v becomes
// the first index of w // the first index of w
size_t d = L.size(); size_t d = L.size();
auto n = it.indexBounds(); It it = v.getJumpIterator();
for (int k = d - 1; k >= 0; --k) { for (int k = d - 1; k >= 0; --k) {
MultiDimVector w(n[k]); MultiDimVector<It> w(it);
std::vector<size_t> indexes(n[k], 0); std::vector<size_t> indexes(w.data.size(), 0);
auto sizes = it.numValuesPerFirstIndex();
for (size_t idx = 0; idx < n[k]; ++idx) {
w.data[idx].resize(sizes[idx]);
}
auto &Lk = L[k]; auto &Lk = L[k];
it.reset(); it.reset();
@ -117,20 +124,16 @@ void multiply_lower_triangular_inplace(It it, std::vector<boost::numeric::ublas:
} }
template <typename It> template <typename It>
void multiply_upper_triangular_inplace(It it, std::vector<boost::numeric::ublas::matrix<double>> U, void multiply_upper_triangular_inplace(std::vector<boost::numeric::ublas::matrix<double>> U,
MultiDimVector &v) { MultiDimVector<It> &v) {
// the multiplication is based on a cyclic permutation of the indices: the last index of v becomes // the multiplication is based on a cyclic permutation of the indices: the last index of v becomes
// the first index of w // the first index of w
size_t d = U.size(); size_t d = U.size();
auto n = it.indexBounds(); It it = v.getJumpIterator();
for (int k = d - 1; k >= 0; --k) { for (int k = d - 1; k >= 0; --k) {
MultiDimVector w(n[k]); MultiDimVector<It> w(it);
std::vector<size_t> indexes(n[k], 0); std::vector<size_t> indexes(w.data.size(), 0);
auto sizes = it.numValuesPerFirstIndex();
for (size_t idx = 0; idx < n[k]; ++idx) {
w.data[idx].resize(sizes[idx]);
}
auto &Uk = U[k]; auto &Uk = U[k];
it.reset(); it.reset();
@ -264,17 +267,17 @@ class SparseTPOperator {
} }
} }
MultiDimVector apply(MultiDimVector input) { MultiDimVector<It> apply(MultiDimVector<It> input) {
prepareApply(); prepareApply();
multiply_upper_triangular_inplace(it, U, input); multiply_upper_triangular_inplace(U, input);
multiply_lower_triangular_inplace(it, L, input); multiply_lower_triangular_inplace(L, input);
return input; return input;
} }
MultiDimVector solve(MultiDimVector rhs) { MultiDimVector<It> solve(MultiDimVector<It> rhs) {
prepareSolve(); prepareSolve();
multiply_lower_triangular_inplace(it, Linv, rhs); multiply_lower_triangular_inplace(Linv, rhs);
multiply_upper_triangular_inplace(it, Uinv, rhs); multiply_upper_triangular_inplace(Uinv, rhs);
return rhs; return rhs;
} }
}; };
@ -306,10 +309,11 @@ SparseTPOperator<It> createInterpolationOperator(It it, Phi phi, X x) {
} }
template <typename It, typename Func, typename X> template <typename It, typename Func, typename X>
MultiDimVector evaluateFunction(It it, Func f, X x) { MultiDimVector<It> evaluateFunction(It it, Func f, X x) {
size_t d = it.dim(); size_t d = it.dim();
auto n = it.indexBounds(); auto n = it.indexBounds();
MultiDimVector v(n[0]); MultiDimVector<It> v(it);
std::vector<size_t> indexes(v.data.size(), 0);
it.reset(); it.reset();
std::vector<double> point(d); std::vector<double> point(d);
@ -324,7 +328,8 @@ MultiDimVector evaluateFunction(It it, Func f, X x) {
double function_value = f(point); double function_value = f(point);
v.data[it.firstIndex()].push_back(function_value); size_t first_index = it.firstIndex();
v.data[first_index][indexes[first_index]++] = function_value;
} }
it.next(); it.next();
@ -334,7 +339,7 @@ MultiDimVector evaluateFunction(It it, Func f, X x) {
} }
template <typename Func, typename It, typename Phi, typename X> template <typename Func, typename It, typename Phi, typename X>
MultiDimVector interpolate(Func f, It it, Phi phi, X x) { MultiDimVector<It> interpolate(Func f, It it, Phi phi, X x) {
auto rhs = evaluateFunction(it, f, x); auto rhs = evaluateFunction(it, f, x);
auto op = createInterpolationOperator(it, phi, x); auto op = createInterpolationOperator(it, phi, x);
return op.solve(rhs); return op.solve(rhs);

View File

@ -70,7 +70,8 @@ inline std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
return os; return os;
} }
inline std::ostream &operator<<(std::ostream &os, fsi::MultiDimVector const &v) { template <typename It>
std::ostream &operator<<(std::ostream &os, fsi::MultiDimVector<It> const &v) {
for (size_t i = 0; i < v.data.size(); ++i) { for (size_t i = 0; i < v.data.size(); ++i) {
std::cout << v.data[i] << "\n\n"; std::cout << v.data[i] << "\n\n";
} }

View File

@ -26,10 +26,10 @@ limitations under the License.
*/ */
void runFunctions() { void runFunctions() {
constexpr size_t d = 30; constexpr size_t d = 8;
size_t bound = 8; size_t bound = 24;
fsi::TemplateBoundedSumIterator<d> it(bound); // fsi::TemplateBoundedSumIterator<d> it(bound);
// fsi::BoundedSumIterator it(d, bound); fsi::BoundedSumIterator it(d, bound);
std::vector<MonomialFunctions> phi(d); std::vector<MonomialFunctions> phi(d);
std::vector<GoldenPointDistribution> x(d); std::vector<GoldenPointDistribution> x(d);