8 #ifndef OPENFPM_NUMERICS_REGRESSION_HPP
9 #define OPENFPM_NUMERICS_REGRESSION_HPP
11 #include "Vector/map_vector.hpp"
12 #include "Space/Shape/Point.hpp"
13 #include "DMatrix/EMatrix.hpp"
14 #include "DCPSE/SupportBuilder.hpp"
15 #include "minter/minter.h"
18 template<
typename vector_type_support,
typename NN_type>
25 template<
typename iterator_type>
26 RegressionSupport(vector_type_support &vd, iterator_type itPoint,
unsigned int requiredSize, support_options opt, NN_type &cellList_in) : domain(vd),
29 rCut = cellList_in.getCellBox().getHigh(0);
36 std::set<grid_key_dx<vector_type_support::dims>> supportCells;
37 supportCells.insert(curCellKey);
40 enlargeSetOfCellsUntilSize(supportCells, requiredSize + 1,
44 keys = getPointsInSetOfCells(supportCells, p, requiredSize, opt);
50 rCut = cellList_in.getCellBox().getHigh(0);
58 auto getNumParticles()
65 vector_type_support &domain;
67 typename vector_type_support::stype rCut;
71 support_options opt) {
72 if (opt == support_options::RADIUS) {
73 auto cell = *set.begin();
75 int n = std::ceil(rCut / cellList.getCellBox().getHigh(0));
76 size_t sz[vector_type_support::dims];
77 for (
int i = 0; i < vector_type_support::dims; i++) {
85 key = cell + key - middle;
86 if (isCellKeyInBounds(key)) {
92 else if (opt == support_options::AT_LEAST_N_PARTICLES) {
96 auto cell = *set.begin();
98 size_t sz[vector_type_support::dims];
102 std::set<grid_key_dx<vector_type_support::dims>> temp_set;
103 for (
int i = 0; i < vector_type_support::dims; i++) {
111 auto key = g_k.
get();
112 key = cell + key - middle;
113 if (isCellKeyInBounds(key)) {
114 temp_set.insert(key);
118 if (getNumElementsInSetOfCells(temp_set) < requiredSize) n++;
127 while (getNumElementsInSetOfCells(set) <
131 for (
const auto el: tmpSet) {
132 for (
unsigned int i = 0; i < vector_type_support::dims; ++i) {
133 const auto pOneEl = el.move(i, +1);
134 const auto mOneEl = el.move(i, -1);
135 if (isCellKeyInBounds(pOneEl)) {
138 if (isCellKeyInBounds(mOneEl)) {
150 size_t requiredSupportSize,
151 support_options opt) {
153 typename vector_type_support::stype dist;
156 bool operator<(
const reord &p)
const {
return this->dist < p.dist; }
162 for (
const auto cellKey: set) {
163 const size_t cellLinId = getCellLinId(cellKey);
164 const size_t elemsInCell = getNumElementsInCell(cellKey);
165 for (
size_t k = 0; k < elemsInCell; ++k) {
166 size_t el = cellList.get(cellLinId, k);
179 if (opt == support_options::RADIUS) {
180 for (
int i = 0; i < rp.
size(); i++) {
181 if (rp.get(i).dist < rCut) {
182 points.add(rp.get(i).offset);
193 else if (opt == support_options::AT_LEAST_N_PARTICLES) {
194 for (
int i = 0; i < rp.
size(); i++) points.add(rp.get(i).offset);
198 for (
int i = 0; i < requiredSupportSize; i++) {
199 points.add(rp.get(i).offset);
207 mem_id
id = cellList.getGrid().LinId(cellKey);
208 return static_cast<size_t>(id);
212 const size_t curCellId = getCellLinId(cellKey);
213 size_t numElements = cellList.getNelements(curCellId);
219 for (
const auto cell : set)
221 tot += getNumElementsInCell(cell);
228 const size_t *cellGridSize = cellList.getGrid().getSize();
229 for (
size_t i = 0; i < vector_type_support::dims; ++i)
231 if (key.
value(i) < 0 || key.
value(i) >= cellGridSize[i])
241 template<
int spatial_dim,
unsigned int prp_
id,
typename MatType = EMatrixXd,
typename VecType = EVectorXd>
246 minter::PolyModel<spatial_dim, MatType, VecType> *model =
nullptr;
247 minter::PolyModel<spatial_dim, MatType, VecType> *deriv_model[spatial_dim];
251 model =
new minter::PolyModel<spatial_dim, MatType, VecType>();
252 model->setDegree(poly_degree, lp_degree);
255 for(
int i = 0;i < spatial_dim;++i)
256 deriv_model[i] =
nullptr;
259 template<
typename vector_type,
typename reg_support_type>
262 int num_particles = support->getNumParticles();
265 MatType points(num_particles, dim);
266 VecType values(num_particles);
268 auto keys = support->getKeys();
269 for(
int i = 0;i < num_particles;++i)
271 for(
int j = 0;j < dim;++j)
272 points(i,j) = vd.
getPos(keys.get(i))[j];
273 values(i) = vd.template getProp<prp_id>(keys.get(i));
277 model =
new minter::PolyModel<spatial_dim, MatType, VecType>(points, values, poly_degree, lp_degree);
280 for(
int i = 0;i < dim;++i)
281 deriv_model[i] =
nullptr;
286 template<
typename vector_type>
292 MatType points(num_particles, dim);
293 VecType values(num_particles);
300 for(
int j = 0;j < dim;++j)
301 points(i,j) = vd.
getPos(key)[j];
303 values(i) = vd.template getProp<prp_id>(key);
310 model =
new minter::PolyModel<spatial_dim, MatType, VecType>(points, values, poly_degree, lp_degree);
312 for(i = 0;i < dim;++i)
313 deriv_model[i] =
nullptr;
317 template<
typename vector_type>
323 MatType points(num_particles, dim);
324 VecType values(num_particles);
331 for(
int j = 0;j < dim;++j)
332 points(i,j) = vd.
getPos(key)[j];
334 values(i) = vd.template getProp<prp_id>(key);
342 minter::PolyModel<spatial_dim, MatType, VecType> *mdl =
nullptr;
351 mdl =
new minter::PolyModel<spatial_dim, MatType, VecType>(points, values, poly_degree, 2.0);
355 for(i = 0;i < num_particles;++i)
357 double pred = mdl->eval(points.block(i,0,1,dim))(0);
358 double err = std::abs(pred - values(i));
364 }
while(error > tolerance);
368 for(i = 0;i < dim;++i)
369 deriv_model[i] =
nullptr;
373 template<
typename vector_type,
typename reg_support_type>
374 void computeCoeffs(
vector_type& vd, reg_support_type& support)
378 auto num_particles = support.getNumParticles();
380 Eigen::MatrixXd points(num_particles, dim);
381 Eigen::VectorXd values(num_particles);
383 auto keys = support.getKeys();
384 for(
int i = 0;i < num_particles;++i)
386 for(
int j = 0;j < dim;++j)
387 points(i,j) = vd.
getPos(keys.get(i))[j];
388 values(i) = vd.template getProp<prp_id>(keys.get(i));
391 model->computeCoeffs(points, values);
395 template<
typename vector_type,
typename reg_support_type>
396 void computeCoeffs(
vector_type& vd, reg_support_type& support,
size_t component)
400 auto num_particles = support.getNumParticles();
402 Eigen::MatrixXd points(num_particles, dim);
403 Eigen::VectorXd values(num_particles);
405 auto keys = support.getKeys();
406 for(
int i = 0;i < num_particles;++i)
408 for(
int j = 0;j < dim;++j)
409 points(i,j) = vd.
getPos(keys.get(i))[j];
410 values(i) = vd.template getProp<prp_id>(keys.get(i))[component];
413 model->computeCoeffs(points, values);
422 for(
int i = 0;i < spatial_dim;++i)
425 delete deriv_model[i];
433 MatType point(1,dim);
434 for(
int j = 0;j < dim;++j)
435 point(0,j) = pos.get(j);
437 return model->eval(point)(0);
442 template<
typename T1,
typename T2>
443 double deriv(T1 pos, T2 deriv_order)
447 MatType point(1,dim);
448 for(
int j = 0;j < dim;++j)
449 point(0,j) = pos.get(j);
451 std::vector<int> order;
452 for(
int j = 0;j < dim;++j)
453 order.push_back(deriv_order.get(j));
455 return model->deriv_eval(point, order)(0);
460 for(
int i = 0;i < spatial_dim;++i)
462 std::vector<int> ord(spatial_dim, 0);
464 deriv_model[i] = model->derivative(ord);
477 for(
int i = 0;i < spatial_dim;++i)
478 res.get(i) = deriv_model[i]->eval(pos);
This class implement the point shape in an N-dimensional space.
__device__ __host__ T distance(const Point< dim, T > &q) const
It calculate the distance between 2 points.
const grid_key_dx< dim > & get() const
Get the actual key.
bool isNext()
Check if there is the next element.
grid_key_dx is the key to access any element in the grid
__device__ __host__ mem_id value(size_t i) const
Get the i index.
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
Grid key for a distributed grid.
vect_dist_key_dx get()
Get the actual key.
static const unsigned int dims
template parameters typedefs
size_t size_local_with_ghost() const
return the local size of the vector
auto getPos(vect_dist_key_dx vec_key) -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
vector_dist_iterator getDomainAndGhostIterator() const
Get an iterator that traverse the particles in the domain.