NEMoSys  0.63.0
A modular, extensible resource with robust automated mesh generation, mesh quality analysis, adaptive mesh refinement, and data transfer between arbitrary meshes.
orthoPoly1D.C
Go to the documentation of this file.
1 /*******************************************************************************
2 * Promesh *
3 * Copyright (C) 2022, IllinoisRocstar LLC. All rights reserved. *
4 * *
5 * Promesh is the property of IllinoisRocstar LLC. *
6 * *
7 * IllinoisRocstar LLC *
8 * Champaign, IL *
9 * www.illinoisrocstar.com *
10 * promesh@illinoisrocstar.com *
11 *******************************************************************************/
12 /*******************************************************************************
13 * This file is part of Promesh *
14 * *
15 * This version of Promesh is free software: you can redistribute it and/or *
16 * modify it under the terms of the GNU Lesser General Public License as *
17 * published by the Free Software Foundation, either version 3 of the License, *
18 * or (at your option) any later version. *
19 * *
20 * Promesh is distributed in the hope that it will be useful, but WITHOUT ANY *
21 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more *
23 * details. *
24 * *
25 * You should have received a copy of the GNU Lesser General Public License *
26 * along with this program. If not, see <https://www.gnu.org/licenses/>. *
27 * *
28 *******************************************************************************/
30 
31 #include <cmath>
32 #include <limits>
33 
34 using Eigen::VectorXd;
35 
36 // constructor
37 orthoPoly1D::orthoPoly1D(int _order, const std::vector<double> &x)
38  : order(_order)
39 {
40  a.resize(_order + 1);
41  b.resize(_order);
42  phi.resize(x.size(), _order + 1);
43  phiTphiInv.resize(_order + 1, _order + 1);
45 }
46 
48 {
49  order = op.order;
50  a = op.a;
51  b = op.b;
52  phi = op.phi;
54 }
55 
57 {
58  if (this != &op)
59  {
60  order = op.order;
61  a = op.a;
62  b = op.b;
63  phi = op.phi;
65  }
66  return *this;
67 }
68 
69 double orthoPoly1D::EvaluateOrthogonal(int power, double xk) const
70 {
71  double p0 = 1.;
72  if (power == 0)
73  return p0;
74  double p1 = xk - a[0];
75  if (power == 1)
76  return p1;
77  double p2 = std::numeric_limits<double>::quiet_NaN();
78  for (int i = 1; i < power; ++i)
79  {
80  p2 = (xk - a[i]) * p1 - b[i - 1] * p0;
81  p0 = p1;
82  p1 = p2;
83  }
84  return p2;
85 }
86 
87 /* Compute coefficients a_m, b_m to be used in recurrence relation for
88  calculating orthogonal polynomial:
89  a_m+1 = (sum_k=0^n-1 x_k*p_m^2(x_k))/(sum_k=0^n-1 p_m^2(x_k))
90  b_m = (sum_k=0^n-1 p_m^2(x_k))/(sum_k=0^n-1 p_m-1^2(x_k)) */
91 void orthoPoly1D::ComputeAB(const std::vector<double> &x)
92 {
93  a[0] = 0.;
94  int n = x.size();
95  for (int i = 0; i < n; ++i)
96  {
97  a[0] += x[i];
98  }
99  a[0] /= n;
100 
101  for (int i = 1; i < order; ++i)
102  {
103  double sum0, sum1, sum2;
104  sum0 = sum1 = sum2 = 0.0;
105  for (int j = 0; j < n; ++j)
106  {
107  double tmp0 = EvaluateOrthogonal(i - 1, x[j]);
108  double tmp1 = EvaluateOrthogonal(i, x[j]);
109  sum0 += tmp0 * tmp0;
110  sum1 += tmp1 * tmp1;
111  sum2 += x[j] * tmp1 * tmp1;
112  }
113  a[i] = sum2 / sum1;
114  b[i - 1] = sum1 / sum0;
115  }
116 }
117 
118 /* Evaluate Orthogonal polynomials at data x and collect them in basis
119  matrix phi */
120 void orthoPoly1D::EvaluateOrthogonals(const std::vector<double> &x)
121 {
122  ComputeAB(x);
123  for (int i = 0; i < order + 1; ++i)
124  {
125  for (int j = 0; j < x.size(); ++j)
126  phi(j, i) = EvaluateOrthogonal(i, x[j]);
127  }
128 }
129 
130 /* Compute inverted matrix for use in normal equation */
131 void orthoPoly1D::ComputePhiTPhiInv(const std::vector<double> &x)
132 {
134  VectorXd tmp = (phi.transpose() * phi).diagonal();
135  for (int i = 0; i < tmp.rows(); ++i)
136  tmp(i) = 1. / tmp(i);
137  phiTphiInv = tmp.asDiagonal();
138 }
orthoPoly1D & operator=(const orthoPoly1D &op)
Definition: orthoPoly1D.C:56
void ComputeAB(const std::vector< double > &x)
Definition: orthoPoly1D.C:91
void EvaluateOrthogonals(const std::vector< double > &x)
Definition: orthoPoly1D.C:120
std::vector< double > a
Definition: orthoPoly1D.H:77
void ComputePhiTPhiInv(const std::vector< double > &x)
Definition: orthoPoly1D.C:131
std::vector< double > b
Definition: orthoPoly1D.H:79
double EvaluateOrthogonal(int power, double xk) const
Definition: orthoPoly1D.C:69
orthoPoly1D()=default
Eigen::MatrixXd phiTphiInv
Definition: orthoPoly1D.H:83
Eigen::MatrixXd phi
Definition: orthoPoly1D.H:81