Add comprehensive testing functions

This commit is contained in:
Folkert Kevelam 2025-03-30 15:33:16 +02:00
parent 8819987c5f
commit 83561bfec1
2 changed files with 120 additions and 13 deletions

View File

@ -1,27 +1,79 @@
(defn square [x] (* x x)) (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)))) (math/abs (- current previous))))
(defn good-enough? [guess x acc]
(< (math/abs (- (square guess) x)) acc))
(defn average [x y] (defn average [x y]
(/ (+ x y) 2)) (/ (+ x y) 2))
(defn improve [guess x] (defn improve [guess x]
(average guess (/ x guess))) (average guess (/ x guess)))
(defn sqrt-iter [prev guess x] (defn sqrt-iter [guess x acc]
(if (good-enough? prev guess) (if (good-enough? guess x acc)
guess guess
(sqrt-iter guess (improve guess x) x))) (sqrt-iter (improve guess x) x acc)))
(defn sqrt [x] (defn sqrt-iter2 [prev guess x acc]
(sqrt-iter 0.0 x x)) (if (good-enough2? prev guess acc)
guess
(sqrt-iter2 guess (improve guess x) x acc)))
(var i 0.0000001) (defn sqrt-iter-max [guess x i acc]
(while (<= i 1000000000000.0) (if (= i 0)
(def meas (sqrt i)) -1
(def rel (/ (- meas (math/sqrt i)) meas)) (if (good-enough? guess x acc)
(print (string/format "Relative error %f=%f, %f" (math/sqrt i) meas rel)) guess
(set i (* i 3.141519))) (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)

55
SICP/exercise_1_7.py Normal file
View File

@ -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")