RTL: Sqrt & Pow

This commit is contained in:
Michael Schimmel
2026-01-13 11:28:11 +01:00
parent 3c5d51f6a8
commit c58da94128
3 changed files with 161 additions and 1 deletions
+70
View File
@@ -1,3 +1,73 @@
(do
;; ---------------------------------------------------------
;; 1. Hilfsfunktion: Berechnet den WMA für einen gegebenen
;; Zeitpunkt auf einer Series.
;; ---------------------------------------------------------
(def calc-wma
(fn [s len]
(do
(def cnt (count s))
;; Wenn nicht genug Daten da sind, gib 0 oder den letzten Wert zurück
(if (< cnt len)
0.0
(do
;; Summe der Gewichte: n * (n + 1) / 2
(def weight-sum (/ (* len (+ len 1)) 2))
;; Rekursive Berechnung der gewichteten Summe
;; Wir iterieren von 0 bis len-1 rückwärts
(def w-total
((fn [i acc]
(if (>= i len)
acc
(do
;; Gewicht: (len - i) -> Höchstes Gewicht für aktuelles Element
(def w (- len i))
;; Wert holen: (get s (count - 1 - i))
(def val (get s (- (- cnt 1) i)))
;; Tail-Recursion
(recur (+ i 1) (+ acc (* w val)))
)))
0 0.0)) ;; Start bei i=0, acc=0.0
;; Ergebnis: Gewichtete Summe / Summe der Gewichte
(/ w-total weight-sum)
)))))
;; ---------------------------------------------------------
;; 2. Die HMA Factory
;; ---------------------------------------------------------
(def create-hma
(fn [len]
(do
;; Konstanten vorberechnen
(def half-len (Round (/ len 2)))
(def sqrt-len (Round (sqrt len)))
;; !!! WICHTIG !!!
;; HMA benötigt eine Glättung der Differenz.
;; Da 'calc-wma' eine Series als Input erwartet, müssen wir
;; die Zwischenwerte (diff) in einer eigenen Series speichern.
;; Diese Series wird in der Closure "gefangen" (captured).
(def diff-series (new-series :Float))
;; Die eigentliche Funktion, die zurückgegeben wird
(fn [source-series]
(do
;; Schritt 1: WMA(n/2) * 2
(def wma-half (calc-wma source-series half-len))
;; Schritt 2: WMA(n)
(def wma-full (calc-wma source-series len))
;; Schritt 3: Differenz berechnen
(def diff (- (* 2 wma-half) wma-full))
;; Schritt 4: Differenz in die interne Series schieben
(add-item diff-series diff)
;; Schritt 5: WMA(sqrt(n)) auf der Differenz-Series berechnen
(calc-wma diff-series sqrt-len)
))
)))
)