Add tasks for all the new languages

This commit is contained in:
Tina Müller 2016-12-05 23:44:36 +01:00
parent 9dc3c2bb62
commit bba7bfd280
13208 changed files with 134745 additions and 0 deletions

View file

@ -0,0 +1,47 @@
(require 'math)
;; converts a finite polynomial (a_0 a_1 .. a_n) to an infinite serie (a_0 ..a_n 0 0 0 ...)
(define (poly->stream list)
(make-stream (lambda(n) (cons (if (< n (length list)) (list-ref list n) 0) (1+ n))) 0))
;; c = a + b , c_n = a_n + b_n
(define (s-add a b)
(make-stream (lambda (n) (cons (+ (stream-ref a n) (stream-ref b n)) (1+ n))) 0))
;; c = a * b , c_n = ∑ (0 ..n) a_i * b_n-i
(define (s-mul-coeff n a b) (sigma (lambda(i) (* (stream-ref a i)(stream-ref b (- n i)))) 0 n))
(define (s-mul a b)
(make-stream (lambda(n) (cons (s-mul-coeff n a b) (1+ n))) 0))
;; b = 1/a ; b_0 = 1/a_0, b_n = - ∑ (1..n) a_i * b_n-i / a_0
(define (s-inv-coeff n a b)
(if (zero? n) (/ (stream-ref a 0))
(- (/ (sigma (lambda(i) (* (stream-ref a i)(stream-ref b (- n i)))) 1 n)
(stream-ref a 0)))))
;; note the self keyword which refers to b = (s-inv a)
(define (s-inv a)
(make-stream (lambda(n) (cons (s-inv-coeff n a self ) (1+ n))) 0))
;; b = (s-k-add k a) = k + a_0, a_1, a_2, ...
(define (s-k-add k a)
(make-stream (lambda(n) (cons
(if(zero? n) (+ k (stream-ref a 0)) (stream-ref a n)) (1+ n))) 0))
;; b = (s-neg a) = -a_0,-a_1, ....
(define (s-neg a)
(make-stream (lambda(n) (cons (- (stream-ref a n)) (1+ n))) 0))
;; b = (s-int a) = ∫ a ; b_0 = 0 by convention, b_n = a_n-1/n
(define (s-int a)
(make-stream (lambda(n) (cons (if (zero? n) 0 (/ (stream-ref a (1- n)) n)) (1+ n))) 0))
;; value of power serie at x, n terms
(define (s-value a x (n 20))
(poly x (take a n)))
;; stream-cons allows mutual delayed references
;; sin = ∫ cos
(define sin-x (stream-cons 0 (stream-rest (s-int cos-x))))
;; cos = 1 - ∫ sin
(define cos-x (stream-cons 1 (stream-rest (s-k-add 1 (s-neg (s-int sin-x))))))

View file

@ -0,0 +1,21 @@
(take cos-x 16)
→ (1 0 -1/2 0 1/24 0 -1/720 0 1/40320 0 -1/3628800 0 1/479001600 0 -1.1470745597729725e-11 0)
(take sin-x 16)
→ (0 1 0 -1/6 0 1/120 0 -1/5040 0 1/362880 0 -1/39916800 0 1.6059043836821613e-10 0 -7.647163731819816e-13)
;; compute (cos PI)
(s-value cos-x PI)
→ -1.0000000035290808
;; check that 1 / (1 - x) = 1 + x + x^1 + x^2 + ...
(define fps-1 (poly->stream '( 1 -1)))
(take fps-1 13)
→ (1 -1 0 0 0 0 0 0 0 0 0 0 0)
(define inv-fps-1 (s-inv fps-1))
(take inv-fps-1 13)
→ (1 1 1 1 1 1 1 1 1 1 1 1 1)
(s-value inv-fps-1 0.5) ;; check that 1 / (1 - 0.5) = 2
→ 1.9999980926513672
(s-value inv-fps-1 0.5 100) ;; 100 terms
→ 2

View file

@ -0,0 +1 @@
1/(1+.)

View file

@ -0,0 +1 @@
def poly(ary): ary[.] // 0;

View file

@ -0,0 +1 @@
(poly([1,2,3]) + poly([-1,-2,-3]))

View file

@ -0,0 +1,13 @@
# Multiply two power series, s and t:
def M(s;t):
. as $i | reduce range(0; 1+$i) as $k
(0; . + ($k|s) * (($i - $k)|t));
# Derivative of the power series, s:
def D(s): (. + 1) as $i | $i * ($i|s);
# Integral of the power series, s,
# with an integration constant equal to 0:
def I(s):
. as $i
| if $i == 0 then 0 else (($i-1)|s) /$i end;

View file

@ -0,0 +1,7 @@
def ps_equal(s; t; k; eps):
def abs: if . < 0 then -. else . end;
reduce range(0;k) as $i
(true;
if . then ((($i|s) - ($i|t))|abs) <= eps
else .
end);

View file

@ -0,0 +1,44 @@
# evaluate p(x) based on the first k terms of polynomial p, where x is the input
def ps_eval(p; k):
. as $x
| reduce range(0;k) as $i
# state: [sum, x^i]
([0, 1];
.[1] as $xn
| ($i|p) as $coeff
| [ .[0] + $coeff * $xn, $x * $xn])
| .[0];
# If |x| < 1 then ps_evaluate(x) will evaluate to p(x) with high precision
# if the coefficients of the polynomial are eventually bounded.
#
# WARNING: ps_evaluate(p) will not detect divergence and is not intended to
# produce accurate results unless the terms of p(x) are reasonably well-behaved.
# For |x| > 1, the result will be null if x^n overflows before convergence is achieved.
#
def ps_evaluate(p):
def abs: if . < 0 then -. else . end;
def eval(p;x):
# state: [i, x^i, sum of i terms, delta, prevdelta]
recurse(
.[0] as $i
| .[1] as $xi
| .[2] as $sum
| .[3] as $delta
| .[4] as $prevdelta
| if $delta < 1e-17 and $prevdelta < 1e-17
and ( $xi < 1e-100
or ( $sum != 0 and
(($delta/$sum) | abs) < 1e-10 and
(($prevdelta/$sum) | abs) < 1e-10) )
then empty
else
($xi * ($i|p)) as $newdelta
| [ $i + 1,
x*$xi,
$sum+$newdelta,
($newdelta|abs), $delta]
end ) ;
. as $x
| [0, 1, 0, 1, 1]
| reduce eval(p; $x) as $vector (0; $vector[2]);

View file

@ -0,0 +1,11 @@
# Utility functions:
def abs: if . < 0 then -. else . end;
# The power series whose only non-zero coefficient is 1 at x^i:
def ps_at(i): if . == i then 1 else 0 end;
# Create an array consisting of the first . coefficients of the power series, p:
def ps_to_array(p): . as $in | reduce range(0;$in) as $i ([]; . + [$i|p]);
def pi: 4 * (1|atan);

View file

@ -0,0 +1,9 @@
# Verify that the first 100 terms of I(cos) and of sin are the same:
ps_equal( I(ps_cos); ps_sin; 100; 1e-15)
# => true
# Verify that the two power series agree when evaluated at pi:
((pi | ps_evaluate(I(ps_cos))) - (pi | ps_evaluate(ps_sin))) | abs < 1e-15
# => true

View file

@ -0,0 +1,9 @@
# Verify that the first 100 terms of cos and (1 - I(sin)) are the same:
ps_equal( ps_cos; ps_at(0) - I(ps_sin); 100; 1e-5)
# => true
# Verify that the two power series agree at pi:
((pi | ps_evaluate(ps_cos)) - (pi | ps_evaluate(ps_at(0) - I(ps_sin)))) | abs < 1e-15
# => true

View file

@ -0,0 +1 @@
1/factorial

View file

@ -0,0 +1,3 @@
def factorial:
reduce range(1; . + 1) as $i
(1; . * $i);

View file

@ -0,0 +1 @@
def ps_exp: 1/factorial;

View file

@ -0,0 +1 @@
1 | ps_evaluate(ps_exp)

View file

@ -0,0 +1 @@
1 | ps_evaluate(1/factorial)

View file

@ -0,0 +1,3 @@
def pow(n):
. as $x | n as $n
| reduce range(0;$n) as $i (1; . * $x);

View file

@ -0,0 +1 @@
1/pow(.)

View file

@ -0,0 +1,4 @@
# ln(1+x) = x - x^2 / 2 + ...
def ln_1px:
def c: if . % 2 == 0 then -1 else 1 end;
. as $i | if $i == 0 then 0 else ($i|c) / $i end;