commit 7e2d2b95a17723ecb886d8acc1951fa32aebb96b
parent dc276738878e0ae293ded6850b7a0023b72ee019
Author: NunoSempere <nuno.sempere@protonmail.com>
Date: Sat, 20 May 2023 22:24:30 -0400
tweak: save some progress.
Diffstat:
4 files changed, 50 insertions(+), 17 deletions(-)
diff --git a/wip/nim/makefile b/wip/nim/makefile
@@ -0,0 +1,2 @@
+build: samples.nim
+ nim c samples.nim
diff --git a/wip/nim/samples b/wip/nim/samples
Binary files differ.
diff --git a/wip/nim/samples.nim b/wip/nim/samples.nim
@@ -1,32 +1,64 @@
-import std/random
import std/math
+import std/random
+
# randomize()
-proc pow2(x:float, y:int): float =
- return pow(x, float(y))
+## Basic math functions
+proc factorial(n: int): int =
+ if n == 0 or n < 0:
+ return 1
+ else:
+ return n * factorial(n - 1)
proc sine(x: float): float =
- let n = 100
+ let n = 8
+ # ^ Taylor will converge really quickly
+ # notice that the factorial of 17 is
+ # already pretty gigantic
var acc = 0.0
for i in 0..n:
- let k = 2*n + 1
- let taylor = pow2(x, k) / float(k)
+ var k = 2*i + 1
+ var taylor = pow(-1, i.float) * pow(x, k.float) / factorial(k).float
acc = acc + taylor
- return acc
+ return acc
-proc log(x: float): float =
+# Helpers for calculating the log function
+
+## Arithmetic-geomtric mean
+proc ag(x: float, y: float): float =
+ let n = 100
+ var a = (x + y)/2.0
+ var b = sqrt(x * y)
+ for i in 0..n:
+ let temp = a
+ a = (a+b)/2.0
+ b = sqrt(b*temp)
+ return a
+
+## Find m such that x * 2^m > 2^100
+
+proc log_slow(x: float): float =
+ # See: <https://en.wikipedia.org/wiki/Natural_logarithm#High_precision>
var y = x - 1
- let n = 1000
+ let n = 100000000
+ var acc = 0.0
for i in 1..n:
- let taylor = pow2(-1.0, n+1) * pow2(y, n) / float(n)
- result = result + taylor
- return result
+ let taylor = pow(-1.0, float(i+1)) * pow(y, i.float) / i.float
+ acc = acc + taylor
+ return acc
+
+proc log(x: float): float =
+ return 1
+
+## Test these functions
+echo factorial(5)
+echo sine(1.0)
+echo log(1.0)
+echo log(2.0)
+## Distribution functions
proc normal(): float =
let u1 = rand(1.0)
let u2 = rand(1.0)
let z = 1
# see https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform#Basic_form
-
-
-echo sine(0.1)
diff --git a/wip/nim/sums/sums.nim b/wip/nim/sums/sums.nim
@@ -1,5 +1,4 @@
import std/math
-# randomize()
proc factorial(n: int): int =
if n == 0 or n < 0:
@@ -19,5 +18,5 @@ proc sine(x: float): float =
acc = acc + taylor
return acc
-# echo factorial(17)
+echo factorial(17)
echo sine(1.0)