Chebyshev coefficients: Difference between revisions

Content added Content deleted
mNo edit summary
Line 709: Line 709:
6.59630183807991E-10
6.59630183807991E-10
-1.0021913854352249E-11</pre>
-1.0021913854352249E-11</pre>

=={{header|jq}}==
{{trans|Wren}}
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''

'''Preliminaries'''
<lang jq>def lpad($len): tostring | ($len - length) as $l | (" " * $l) + .;
def rpad($len; $fill): tostring | ($len - length) as $l | . + ($fill * $l)[:$l];

# Format a decimal number so that there are at least `left` characters
# to the left of the decimal point, and at most `right` characters to its right.
# No left-truncation occurs, so `left` can be specified as 0 to prevent left-padding.
# If tostring has an "e" then eparse as defined below is used.
def pp(left; right):
def lpad: if (left > length) then ((left - length) * " ") + . else . end;
def eparse: index("e") as $ix | (.[:$ix]|pp(left;right)) + .[$ix:];
tostring as $s
| $s
| if test("e") then eparse
else index(".") as $ix
| ((if $ix then $s[0:$ix] else $s end) | lpad) + "." +
(if $ix then $s[$ix+1:] | .[0:right] else "" end)
end;</lang>
'''Chebyshev Coefficients'''
<lang jq>def mapRange($x; $min; $max; $minTo; $maxTo):
(($x - $min)/($max - $min))*($maxTo - $minTo) + $minTo;
def chebCoeffs(func; n; min; max):
(1 | atan * 4) as $pi
| reduce range(0;n) as $i ([]; # coeffs
((mapRange( ($pi * ($i + 0.5) / n)|cos; -1; 1; min; max) | func) * 2 / n) as $f
| reduce range(0;n) as $j (.;
.[$j] += $f * ($pi * $j * (($i + 0.5) / n)|cos)) );
def chebApprox(x; n; min; max; coeffs):
if n < 2 or (coeffs|length) < 2 then "'n' can't be less than 2." | error
else { a: 1,
b: mapRange(x; min; max; -1; 1) }
|.res = coeffs[0]/2 + coeffs[1]*.b
|.xx = 2 * .b
| reduce range(2;n) as $i (.;
(.xx * .b - .a) as $c
| .res = (.res + (coeffs[$i]*$c))
| .a = .b
| .b = $c)
| .res
end ;

def task:
[10, 0, 1] as [$n, $min, $max]
| chebCoeffs(cos; $n; $min; $max) as $coeffs
| "Coefficients:",
($coeffs[]|pp(2;14)),
"\nApproximations:\n x func(x) approx diff",
(range(0;21) as $i
| mapRange($i; 0; 20; $min; $max) as $x
| ($x|cos) as $f
| chebApprox($x; $n; $min; $max; $coeffs) as $approx
| ($approx - $f) as $diff
| ($diff|tostring) as $diffStr
| $diffStr[-4:] as $e
| $diffStr[0:-4] as $diffStr
| (if $diff >= 0 then " " + $diffStr[:4] else $diffStr[0:5] end) as $diffStr
| [ ($x|pp(0;3)|rpad(4;"0")),
($f|pp(0;8)|rpad(10;"0")),
($approx|pp(0;8)),
($diffStr + $e)]
| join(" ") );

task</lang>
{{out}}
<pre>
Coefficients:
1.64716947539031
-0.23229937161517
-0.05371511462204
0.00245823526698
0.00028211905743
-7.72222915562670e-06
-5.89855645688475e-07
1.15214280338449e-08
6.59629580124221e-10
-1.00220526322303e-11

Approximations:
x func(x) approx diff
0.00 1.00000000 1.00000000 4.66e-13
0.05 0.99875026 0.99875026 -9.21e-14
0.10 0.99500416 0.99500416 4.62e-13
0.15 0.98877107 0.98877107 -4.74e-14
0.20 0.98006657 0.98006657 -4.60e-13
0.25 0.96891242 0.96891242 -2.32e-13
0.30 0.95533648 0.95533648 2.61e-13
0.35 0.93937271 0.93937271 4.60e-13
0.40 0.92106099 0.92106099 1.98e-13
0.45 0.90044710 0.90044710 -2.47e-13
0.50 0.87758256 0.87758256 -4.59e-13
0.55 0.85252452 0.85252452 -2.46e-13
0.60 0.82533561 0.82533561 1.95e-13
0.65 0.79608379 0.79608379 4.53e-13
0.70 0.76484218 0.76484218 2.55e-13
0.75 0.73168886 0.73168886 -2.26e-13
0.80 0.69670670 0.69670670 -4.46e-13
0.85 0.65998314 0.65998314 -4.45e-14
0.90 0.62160996 0.62160996 4.44e-13
0.95 0.58168308 0.58168308 -9.01e-14
1.00 0.54030230 0.54030230 4.47e-13
</pre>



=={{header|Julia}}==
=={{header|Julia}}==