From 83561bfec10a4121f57b9a4a57bc95bea994f883 Mon Sep 17 00:00:00 2001 From: Folkert Kevelam Date: Sun, 30 Mar 2025 15:33:16 +0200 Subject: [PATCH] Add comprehensive testing functions --- SICP/exercise_1_7.janet | 78 ++++++++++++++++++++++++++++++++++------- SICP/exercise_1_7.py | 55 +++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 13 deletions(-) create mode 100644 SICP/exercise_1_7.py diff --git a/SICP/exercise_1_7.janet b/SICP/exercise_1_7.janet index efd0e64..2a3d77e 100644 --- a/SICP/exercise_1_7.janet +++ b/SICP/exercise_1_7.janet @@ -1,27 +1,79 @@ (defn square [x] (* x x)) -(defn good-enough? [previous current] +(defn good-enough2? [previous current acc] (>= - (* current 0.001) + (* current acc) (math/abs (- current previous)))) +(defn good-enough? [guess x acc] + (< (math/abs (- (square guess) x)) acc)) + (defn average [x y] (/ (+ x y) 2)) (defn improve [guess x] (average guess (/ x guess))) -(defn sqrt-iter [prev guess x] - (if (good-enough? prev guess) +(defn sqrt-iter [guess x acc] + (if (good-enough? guess x acc) guess - (sqrt-iter guess (improve guess x) x))) + (sqrt-iter (improve guess x) x acc))) -(defn sqrt [x] - (sqrt-iter 0.0 x x)) +(defn sqrt-iter2 [prev guess x acc] + (if (good-enough2? prev guess acc) + guess + (sqrt-iter2 guess (improve guess x) x acc))) -(var i 0.0000001) -(while (<= i 1000000000000.0) - (def meas (sqrt i)) - (def rel (/ (- meas (math/sqrt i)) meas)) - (print (string/format "Relative error %f=%f, %f" (math/sqrt i) meas rel)) - (set i (* i 3.141519))) +(defn sqrt-iter-max [guess x i acc] + (if (= i 0) + -1 + (if (good-enough? guess x acc) + guess + (sqrt-iter-max (improve guess x) x (- i 1) acc)))) + +(defn sqrt [x acc] + (sqrt-iter 1.0 x acc)) + +(defn sqrt2 [x acc] + (sqrt-iter2 0.0 x x acc)) + +(defn sqrt-max [x acc] + (sqrt-iter-max 1.0 x 500 acc)) + +(defn relative-error [i f] + (def measurement (sqrt2 i 0.0001)) + (def measurement2 (sqrt2 i 0.00001)) + (def measurement3 (sqrt2 i 0.000001)) + (def actual (math/sqrt i)) + (def rel-error (/ (- measurement actual) measurement)) + (def rel-error2 (/ (- measurement2 actual) measurement2)) + (def rel-error3 (/ (- measurement3 actual) measurement3)) + (file/write f (string/format "%e,%e,%e,%e\n" i rel-error rel-error2 rel-error3))) + +(defn find-breakpoint [] + (var found? false) + (var base 1.0e12) + (var minimum 1.0e-3) + (var num 0.0) + (while (not found?) + (def test (+ num base)) + (if (>= (sqrt-max test 0.001) 0) + (set num (+ num base)) + (do + (set base (/ base 10.0)) + (if (< base minimum) + (set found? true))))) + num) + +(print (find-breakpoint)) + +(def f (file/open "exercise_1_7_data.csv" :w)) +(file/write f "i,0.001,0.0001,0.00001\n") +(var total (* 2 50)) +(var num 1e25) +(while (> total 0) + (relative-error num f) + (set num (/ num (math/sqrt 10.0))) + (set total (- total 1))) + +(file/close f) diff --git a/SICP/exercise_1_7.py b/SICP/exercise_1_7.py new file mode 100644 index 0000000..070ef1a --- /dev/null +++ b/SICP/exercise_1_7.py @@ -0,0 +1,55 @@ +import matplotlib.pyplot as plt +import numpy as np +import csv +import math + +def read_csv(filename): + data = list() + header = None + with open(filename, "r") as file: + reader = csv.reader(file) + header = next(reader, None) + print(header) + for row in reader: + data.append([float(d) for d in row]) + + return header, data + +def main(filename): + header, data = read_csv(filename) + + x = [d[0] for d in data] + y = dict() + for h in range(1, len(header)): + y[header[h]] = list() + + for d in data: + for idx in range(0, len(d)-1): + y[header[idx+1]].append(d[idx+1]) + + min_x = min(x) + max_x = max(x) + + min_x_tick_power = math.floor(math.log10(min_x)) + max_x_tick_power = math.ceil(math.log10(max_x)) + + xticks = [10**p for p in range(min_x_tick_power, max_x_tick_power)] + + headers = list() + for key,value in y.items(): + plt.plot(x, value) + headers.append(key) + + plt.legend(["acc={}".format(h) for h in headers]) + + plt.xscale("log") + plt.grid(True) + plt.xlabel("Input to sqrt()") + plt.ylabel("Relative Error") + #plt.xticks(xticks) + plt.title("Relative error of sqrt()") + plt.show() + + +if __name__ == "__main__": + main("exercise_1_7_data.csv")