增加拉格朗日插值和多项式拟合算法。

Signed-off-by: lion.chan <cy187lion@sina.com>
This commit is contained in:
lion.chan 2022-08-25 15:55:52 +08:00
parent efdd665289
commit d74958ebeb
2 changed files with 215 additions and 0 deletions

View File

@ -0,0 +1,51 @@
static double domega(const double* xn, const unsigned int n, const unsigned int k, const double x);
/**
* @brief
*
* @param xn x
* @param yn y
* @param n
* @param x x
* @return double y
*/
double Lagrange(const double* xn, const double* yn, const unsigned int n, const double x) {
unsigned int i;
double l = 0.0;
for (i=0; i<n; i++)
l += yn[i]*domega(xn, n, i, x);
return l;
}
static double domega(const double* xn, const unsigned int n, const unsigned int k, const double x) {
unsigned int i;
double omega=1.0;
double omega_deri = 1.0;
for (i=0; i<n; i++) {
if (i==k)
continue;
omega *= (x-xn[i]);
omega_deri *= (xn[k] - xn[i]);
}
return omega/omega_deri;
}
/** Demo */
static double Xn[] = {0, 0.3000, 0.6000, 0.9000, 1.2000, 1.5000, 1.8000, 2.1000, 2.4000, 2.7000, 3.0000};
static double Yn[] = {2.0000, 2.3780, 3.9440, 7.3460, 13.2320, 22.2500, 35.0480, 52.2740, 74.5760, 102.6020, 137.0000};
/**
* @brief
*
* @return int
*/
int main(void) {
double out = 0.0;
out = Lagrange(Xn, Yn, 11, 1.5);
return 0;
}

164
Algorithm/DSP/Polyfit.c Normal file
View File

@ -0,0 +1,164 @@
/**
* @brief
*
* @param dependentValues
* @param independentValues
* @param countOfElements
* @param order
* @param coefficients
* @return int
*/
int Polyfit(const double* const dependentValues,
const double* const independentValues,
unsigned int countOfElements,
unsigned int order,
double* coefficients)
{
// Declarations...
// ----------------------------------
enum {maxOrder = 5};
double B[maxOrder+1] = {0.0};
double P[((maxOrder+1) * 2)+1] = {0.0};
double A[(maxOrder + 1)*2*(maxOrder + 1)] = {0.0};
double x, y, powx;
unsigned int ii, jj, kk;
// Verify initial conditions....
// ----------------------------------
// This method requires that the countOfElements >
// (order+1)
if (countOfElements <= order)
return -1;
// This method has imposed an arbitrary bound of
// order <= maxOrder. Increase maxOrder if necessary.
if (order > maxOrder)
return -1;
// Begin Code...
// ----------------------------------
// Identify the column vector
for (ii = 0; ii < countOfElements; ii++)
{
x = dependentValues[ii];
y = independentValues[ii];
powx = 1;
for (jj = 0; jj < (order + 1); jj++)
{
B[jj] = B[jj] + (y * powx);
powx = powx * x;
}
}
// Initialize the PowX array
P[0] = countOfElements;
// Compute the sum of the Powers of X
for (ii = 0; ii < countOfElements; ii++)
{
x = dependentValues[ii];
powx = dependentValues[ii];
for (jj = 1; jj < ((2 * (order + 1)) + 1); jj++)
{
P[jj] = P[jj] + powx;
powx = powx * x;
}
}
// Initialize the reduction matrix
//
for (ii = 0; ii < (order + 1); ii++)
{
for (jj = 0; jj < (order + 1); jj++)
{
A[(ii * (2 * (order + 1))) + jj] = P[ii+jj];
}
A[(ii*(2 * (order + 1))) + (ii + (order + 1))] = 1;
}
// Move the Identity matrix portion of the redux matrix
// to the left side (find the inverse of the left side
// of the redux matrix
for (ii = 0; ii < (order + 1); ii++)
{
x = A[(ii * (2 * (order + 1))) + ii];
if (x != 0.0)
{
for (kk = 0; kk < (2 * (order + 1)); kk++)
{
A[(ii * (2 * (order + 1))) + kk] =
A[(ii * (2 * (order + 1))) + kk] / x;
}
for (jj = 0; jj < (order + 1); jj++)
{
if ((jj - ii) != 0)
{
y = A[(jj * (2 * (order + 1))) + ii];
for (kk = 0; kk < (2 * (order + 1)); kk++)
{
A[(jj * (2 * (order + 1))) + kk] =
A[(jj * (2 * (order + 1))) + kk] -
y * A[(ii * (2 * (order + 1))) + kk];
}
}
}
}
else
{
// Cannot work with singular matrices
return -1;
}
}
// Calculate and Identify the coefficients
for (ii = 0; ii < (order + 1); ii++)
{
for (jj = 0; jj < (order + 1); jj++)
{
x = 0;
for (kk = 0; kk < (order + 1); kk++)
{
x = x + (A[(ii * (2 * (order + 1))) + (kk + (order + 1))] *
B[kk]);
}
coefficients[ii] = x;
}
}
return 0;
}
/** Demo */
static double Xn[] = {0, 0.3000, 0.6000, 0.9000, 1.2000, 1.5000, 1.8000, 2.1000, 2.4000, 2.7000, 3.0000};
static double Yn[] = {2.0000, 2.3780, 3.9440, 7.3460, 13.2320, 22.2500, 35.0480, 52.2740, 74.5760, 102.6020, 137.0000};
/**
* @brief
*
* @return int
*/
int main(void)
{
double out = 0.0;
unsigned int i;
double coff[3];
polyfit(Xn, Yn, 11, 2, coff);
for (i=0; i<3; i++)
{
out += coff[i]*pow(Xn[4], i);
}
return 0;
}