Chebyshev coefficients: Difference between revisions
Content added Content deleted
m (→{{header|REXX}}: used a more idiomatic expression for calculation of numeric digits.) |
|||
Line 182: | Line 182: | ||
} |
} |
||
</lang> |
</lang> |
||
=={{header|C#|C sharp}}== |
|||
{{trans|C++}} |
|||
<lang csharp>using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
namespace Chebyshev { |
|||
class Program { |
|||
struct ChebyshevApprox { |
|||
public readonly List<double> coeffs; |
|||
public readonly Tuple<double, double> domain; |
|||
public ChebyshevApprox(Func<double, double> func, int n, Tuple<double, double> domain) { |
|||
coeffs = ChebCoef(func, n, domain); |
|||
this.domain = domain; |
|||
} |
|||
public double Call(double x) { |
|||
return ChebEval(coeffs, domain, x); |
|||
} |
|||
} |
|||
static double AffineRemap(Tuple<double, double> from, double x, Tuple<double, double> to) { |
|||
return to.Item1 + (x - from.Item1) * (to.Item2 - to.Item1) / (from.Item2 - from.Item1); |
|||
} |
|||
static List<double> ChebCoef(List<double> fVals) { |
|||
int n = fVals.Count; |
|||
double theta = Math.PI / n; |
|||
List<double> retval = new List<double>(); |
|||
for (int i = 0; i < n; i++) { |
|||
retval.Add(0.0); |
|||
} |
|||
for (int ii = 0; ii < n; ii++) { |
|||
double f = fVals[ii] * 2.0 / n; |
|||
double phi = (ii + 0.5) * theta; |
|||
double c1 = Math.Cos(phi); |
|||
double s1 = Math.Sin(phi); |
|||
double c = 1.0; |
|||
double s = 0.0; |
|||
for (int j = 0; j < n; j++) { |
|||
retval[j] += f * c; |
|||
// update c -> cos(j*phi) for next value of j |
|||
double cNext = c * c1 - s * s1; |
|||
s = c * s1 + s * c1; |
|||
c = cNext; |
|||
} |
|||
} |
|||
return retval; |
|||
} |
|||
static List<double> ChebCoef(Func<double, double> func, int n, Tuple<double, double> domain) { |
|||
double remap(double x) { |
|||
return AffineRemap(new Tuple<double, double>(-1.0, 1.0), x, domain); |
|||
} |
|||
double theta = Math.PI / n; |
|||
List<double> fVals = new List<double>(); |
|||
for (int i = 0; i < n; i++) { |
|||
fVals.Add(0.0); |
|||
} |
|||
for (int ii = 0; ii < n; ii++) { |
|||
fVals[ii] = func(remap(Math.Cos((ii + 0.5) * theta))); |
|||
} |
|||
return ChebCoef(fVals); |
|||
} |
|||
static double ChebEval(List<double> coef, double x) { |
|||
double a = 1.0; |
|||
double b = x; |
|||
double c; |
|||
double retval = 0.5 * coef[0] + b * coef[1]; |
|||
var it = coef.GetEnumerator(); |
|||
it.MoveNext(); |
|||
it.MoveNext(); |
|||
while (it.MoveNext()) { |
|||
double pc = it.Current; |
|||
c = 2.0 * b * x - a; |
|||
retval += pc * c; |
|||
a = b; |
|||
b = c; |
|||
} |
|||
return retval; |
|||
} |
|||
static double ChebEval(List<double> coef, Tuple<double, double> domain, double x) { |
|||
return ChebEval(coef, AffineRemap(domain, x, new Tuple<double, double>(-1.0, 1.0))); |
|||
} |
|||
static void Main() { |
|||
const int N = 10; |
|||
ChebyshevApprox fApprox = new ChebyshevApprox(Math.Cos, N, new Tuple<double, double>(0.0, 1.0)); |
|||
Console.WriteLine("Coefficients: "); |
|||
foreach (var c in fApprox.coeffs) { |
|||
Console.WriteLine("\t{0: 0.00000000000000;-0.00000000000000;zero}", c); |
|||
} |
|||
Console.WriteLine("\nApproximation:\n x func(x) approx diff"); |
|||
const int nX = 20; |
|||
const int min = 0; |
|||
const int max = 1; |
|||
for (int i = 0; i < nX; i++) { |
|||
double x = AffineRemap(new Tuple<double, double>(0, nX), i, new Tuple<double, double>(min, max)); |
|||
double f = Math.Cos(x); |
|||
double approx = fApprox.Call(x); |
|||
Console.WriteLine("{0:0.000} {1:0.00000000000000} {2:0.00000000000000} {3:E}", x, f, approx, approx - f); |
|||
} |
|||
} |
|||
} |
|||
}</lang> |
|||
{{out}} |
|||
<pre>Coefficients: |
|||
1.64716947539031 |
|||
-0.23229937161517 |
|||
-0.05371511462205 |
|||
0.00245823526698 |
|||
0.00028211905743 |
|||
-0.00000772222916 |
|||
-0.00000058985565 |
|||
0.00000001152143 |
|||
0.00000000065963 |
|||
-0.00000000001002 |
|||
Approximation: |
|||
x func(x) approx diff |
|||
0.000 1.00000000000000 1.00000000000047 4.689582E-013 |
|||
0.050 0.99875026039497 0.99875026039487 -9.370282E-014 |
|||
0.100 0.99500416527803 0.99500416527849 4.622969E-013 |
|||
0.150 0.98877107793604 0.98877107793600 -4.662937E-014 |
|||
0.200 0.98006657784124 0.98006657784078 -4.604095E-013 |
|||
0.250 0.96891242171065 0.96891242171041 -2.322587E-013 |
|||
0.300 0.95533648912561 0.95533648912587 2.609024E-013 |
|||
0.350 0.93937271284738 0.93937271284784 4.606315E-013 |
|||
0.400 0.92106099400289 0.92106099400308 1.980638E-013 |
|||
0.450 0.90044710235268 0.90044710235243 -2.473577E-013 |
|||
0.500 0.87758256189037 0.87758256188991 -4.586331E-013 |
|||
0.550 0.85252452205951 0.85252452205926 -2.461364E-013 |
|||
0.600 0.82533561490968 0.82533561490988 1.961764E-013 |
|||
0.650 0.79608379854906 0.79608379854951 4.536371E-013 |
|||
0.700 0.76484218728449 0.76484218728474 2.553513E-013 |
|||
0.750 0.73168886887382 0.73168886887359 -2.267075E-013 |
|||
0.800 0.69670670934717 0.69670670934672 -4.467537E-013 |
|||
0.850 0.65998314588498 0.65998314588494 -4.485301E-014 |
|||
0.900 0.62160996827066 0.62160996827111 4.444223E-013 |
|||
0.950 0.58168308946388 0.58168308946379 -8.992806E-014</pre> |
|||
=={{header|D}}== |
=={{header|D}}== |