std::vector<std::vector<T>> group(std::vector<T> v, F similar) { UnionFind uf(v.size()); for (size_t i = 0; i < v.size(); ++i) { for (size_t j = i + 1; j < v.size(); ++j) { if (similar(v[i], v[j])) { uf.join(i, j); } } } std::vector<int> idxmap(v.size(), -1); std::vector<std::vector<T>> vs; for (size_t i = 0; i < v.size(); ++i) { size_t set = uf.find(i); int group = idxmap[set]; if (group < 0) { idxmap[set] = vs.size(); vs.emplace_back(1, v[i]); } else { vs[group].push_back(v[i]); } } return vs; }
void KNDdeTorusCollocation::Save(const char* dat, const char* idx, const KNVector& in) { // writing to file for plotting std::ofstream ff(dat); for (size_t i2 = 0; i2 < nint2; i2++) { for (size_t j2 = 0; j2 < ndeg2; j2++) { for (size_t i1 = 0; i1 < nint1; i1++) { for (size_t j1 = 0; j1 < ndeg1; j1++) { const size_t idx1 = idxmap(j1, j2, i1, i2); for (size_t p = 0; p < NDIM; p++) { ff << in(p + NDIM*idx1) << "\t"; } } } ff << "\n"; } } std::ofstream gg(idx); for (size_t i1 = 0; i1 < nint1; i1++) { for (size_t j1 = 0; j1 < ndeg1; j1++) { const double t1 = (mesh1(j1) + i1) / ((double)nint1); gg << t1 << "\t"; } } gg << "\n"; for (size_t i2 = 0; i2 < nint2; i2++) { for (size_t j2 = 0; j2 < ndeg2; j2++) { const double t2 = (mesh2(j2) + i2) / ((double)nint2); gg << t2 << "\t"; } } gg << "\n"; }
void KNDdeTorusCollocation::importSolution(KNVector& out, KNVector& in) { for (size_t i2 = 0; i2 < nint2; i2++) { for (size_t i1 = 0; i1 < nint1; i1++) { for (size_t j2 = 0; j2 < ndeg2; j2++) { for (size_t j1 = 0; j1 < ndeg1; j1++) { const size_t idx1 = idxmap(j1, j2, i1, i2); for (size_t p = 0; p < NDIM; p++) { out(p + NDIM*idx1) = in(p + NDIM * (j1 + i1 * ndeg1)); } } } } } }
void KNDdeTorusCollocation::init(const KNVector& sol, const KNVector& par) { double* t1 = new double[NTAU+1]; double* t2 = new double[NTAU+1]; for (size_t i2 = 0; i2 < nint2; i2++) { for (size_t i1 = 0; i1 < nint1; i1++) { for (size_t j2 = 0; j2 < ndeg2; j2++) { for (size_t j1 = 0; j1 < ndeg1; j1++) { const size_t idx = idxmap(j1, j2, i1, i2); // this is a unique time1(idx) = ((double)i1 + col1(j1)) / nint1; time2(idx) = ((double)i2 + col2(j2)) / nint2; } } } } sys->p_tau(p_tau, time1, par); p_xx.clear(); for (size_t idx = 0; idx < time1.size(); ++idx) { t1[0] = time1(idx); t2[0] = time2(idx); for (size_t k = 0; k < NTAU; k++) { t1[1+k] = (t1[0] - p_tau(k,idx) / par(0)) - floor(t1[0] - p_tau(k,idx) / par(0)); t2[1+k] = (t2[0] - par(RHO) * p_tau(k,idx) / par(0)) - floor(t2[0] - par(RHO) * p_tau(k,idx) / par(0)); } for (size_t k = 0; k < NTAU + 1; k++) { size_t i1 = static_cast<size_t>(floor(nint1 * t1[k])); size_t i2 = static_cast<size_t>(floor(nint2 * t2[k])); // some error checking if ((t1[k] > 1.0) || (t2[k] > 1.0) || (t1[k] < 0.0) || (t2[k] < 0.0)) std::cout << "Er "; if ((i1 >= nint1) || (i2 >= nint2)) std::cout << "Ei "; // end error checking for (size_t j2 = 0; j2 < ndeg2 + 1; j2++) { for (size_t j1 = 0; j1 < ndeg1 + 1; j1++) { const size_t idxKK = idxkk(j1, j2, k); kk(idxKK,idx) = idxmap(j1, j2, i1, i2); ee(idxKK,idx) = idxKK; } } } // sorting comp aa(kk.pointer(0,idx)); std::sort(ee.pointer(0,idx), ee.pointer(0,idx) + (NTAU + 1)*(ndeg1 + 1)*(ndeg2 + 1), aa); // filtering same indices rr(ee(0,idx),idx) = 0; size_t nz = 0; for (size_t i = 1; i < (NTAU + 1)*(ndeg1 + 1)*(ndeg2 + 1); i++) { if (kk(ee(i-1,idx),idx) != kk(ee(i,idx),idx)) nz++; rr(ee(i,idx),idx) = nz; } // interpolate the solution for (size_t k = 1; k < NTAU + 1; k++) { const double c1 = nint1 * t1[k] - floor(nint1 * t1[k]); const double c2 = nint2 * t2[k] - floor(nint2 * t2[k]); for (size_t j2 = 0; j2 < ndeg2 + 1; j2++) { for (size_t j1 = 0; j1 < ndeg1 + 1; j1++) { const size_t idxKK = idxkk(j1, j2, k); const double cf = poly_lgr_eval(mesh1, j1, c1) * poly_lgr_eval(mesh2, j2, c2); for (size_t p = 0; p < NDIM; p++) { p_xx(p, k - 1, idx) += cf * sol(p + NDIM * kk(idxKK, idx)); } } } } // derivatives at all delays for (size_t k = 0; k < NTAU + 1; k++) { const double c1 = nint1 * t1[k] - floor(nint1 * t1[k]); const double c2 = nint2 * t2[k] - floor(nint2 * t2[k]); for (size_t j2 = 0; j2 < ndeg2 + 1; j2++) { for (size_t j1 = 0; j1 < ndeg1 + 1; j1++) { const size_t idxKK = idxkk(j1, j2, k); const double cf1 = poly_dlg_eval(mesh1, j1, c1) * nint1 * poly_lgr_eval(mesh2, j2, c2); const double cf2 = poly_lgr_eval(mesh1, j1, c1) * poly_dlg_eval(mesh2, j2, c2) * nint2; for (size_t p = 0; p < NDIM; p++) { p_xx(p, NTAU + 2*k, idx) += cf1 * sol(p + NDIM * kk(idxKK, idx)); p_xx(p, NTAU + 2*k + 1, idx) += cf2 * sol(p + NDIM * kk(idxKK, idx)); } } } } } // for (int idx = 0; idx < time1.size(); ++idx) std::cout<<p_xx(0, NTAU, idx)<<"\t"; // std::cout<<"\np_xx(0,...) was\n"; delete[] t2; delete[] t1; }