/* * Copyright © 2005 Ondra Kamenik * Copyright © 2019 Dynare Team * * This file is part of Dynare. * * Dynare is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Dynare is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Dynare. If not, see . */ #include "product.hh" #include "symmetry.hh" #include #include /* This constructs a product iterator corresponding to index (j0,0,…,0). */ prodpit::prodpit(const ProductQuadrature &q, int j0, int l) : prodq(q), level(l), npoints(q.uquad.numPoints(l)), jseq(q.dimen(), 0), end_flag(false), sig{q.dimen()}, p{q.dimen()} { if (j0 < npoints) { jseq[0] = j0; setPointAndWeight(); } else end_flag = true; } bool prodpit::operator==(const prodpit &ppit) const { return &prodq == &ppit.prodq && end_flag == ppit.end_flag && jseq == ppit.jseq; } prodpit & prodpit::operator++() { int i = prodq.dimen()-1; jseq[i]++; while (i >= 0 && jseq[i] == npoints) { jseq[i] = 0; i--; if (i >= 0) jseq[i]++; } sig.signalAfter(std::max(i, 0)); if (i == -1) end_flag = true; if (!end_flag) setPointAndWeight(); return *this; } /* This calculates the weight and sets point coordinates from the indices. */ void prodpit::setPointAndWeight() { w = 1.0; for (int i = 0; i < prodq.dimen(); i++) { p[i] = (prodq.uquad).point(level, jseq[i]); w *= (prodq.uquad).weight(level, jseq[i]); } } /* Debug print. */ void prodpit::print() const { auto ff = std::cout.flags(); std::cout << "j=["; for (int i = 0; i < prodq.dimen(); i++) std::cout << std::setw(2) << jseq[i]; std::cout << std::showpos << std::fixed << std::setprecision(3) << "] " << std::setw(4) << w << "*("; for (int i = 0; i < prodq.dimen()-1; i++) std::cout << std::setw(4) << p[i] << ' '; std::cout << std::setw(4) << p[prodq.dimen()-1] << ')' << std::endl; std::cout.flags(ff); } ProductQuadrature::ProductQuadrature(int d, const OneDQuadrature &uq) : QuadratureImpl(d), uquad(uq) { // TODO: check d≥1 } /* This calls prodpit constructor to return an iterator which points approximatelly at ‘ti’-th portion out of ‘tn’ portions. First we find out how many points are in the level, and then construct an interator (j0,0,…,0) where j0=ti·npoints/tn. */ prodpit ProductQuadrature::begin(int ti, int tn, int l) const { // TODO: raise if l