Skip to content

Commit

Permalink
More Code Style / Disable PR CI tests (#7)
Browse files Browse the repository at this point in the history
* code style and disable PR tests to save resources for now

* docstrings

* quicker tests / code style

* re-enable PR test to check perf / runtime in minutes

* disable PR tests

* test GA error condition

* re-enable mods with 100, 1/100

* eval style

* modify style

* CI badge
  • Loading branch information
ogeagla authored Feb 15, 2024
1 parent 58b2a33 commit a75b922
Show file tree
Hide file tree
Showing 16 changed files with 191 additions and 142 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/clojure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ name: Clojure CI
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
# pull_request:
# branches: [ "master" ]

jobs:
build:
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# closyr

[![Clojure CI](https://github.com/ogeagla/closyr/actions/workflows/clojure.yml/badge.svg?branch=master)](https://github.com/ogeagla/closyr/actions/workflows/clojure.yml)

![icon_v5_qtr.png](resources%2Ficons%2Ficon_v5_qtr.png)

A Symbolic Regression tool to search for symbolic expressions which minimize residuals to an objective, written in Clojure.
Expand Down
3 changes: 2 additions & 1 deletion src/closyr/ga.clj
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,5 @@
:mutation-fn mutation-fn
:crossover-fn crossover-fn}))
(catch Exception e
(log/error "Err in evolve: " e))))
(log/error "Err in evolve: " e)
(throw e))))
2 changes: 1 addition & 1 deletion src/closyr/ops/common.clj
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@
(go-loop [c 0]
(when-not @done?*
;; wait sequence in ms looks like: 100, 316, 1000, ...
(<! (timeout (int (Math/pow (/ *long-simplify-thresh-ms* 200)
(<! (timeout (int (Math/pow (max 2.0 (/ *long-simplify-thresh-ms* 200))
(+ 1.5 (/ c 4))))))
(when (> c 6)
(reset! report-done?* true)
Expand Down
70 changes: 40 additions & 30 deletions src/closyr/ops/eval.clj
Original file line number Diff line number Diff line change
Expand Up @@ -54,43 +54,53 @@
(str expr) " : " (or (.getMessage e) e)))))


(defn- parseable-eval-result?
[eval-p]
(not (or (nil? eval-p)
(= "Indeterminate" (str eval-p)))))


(defn- result-args->doubles
[^IExpr eval-p i]
(try
(let [^IExpr res (.getArg eval-p (inc i) F/Infinity)]
(if (.isReal res)
(ops-common/expr->double res)
Double/POSITIVE_INFINITY))
(catch Exception e
(log/error "Error in evaling function on input values: " (str eval-p) " : " e)
Double/POSITIVE_INFINITY)))


(defn- result-args->constant-input
[^IExpr eval-p ^IExpr new-expr i]
(try
(let [^IExpr arg0 (.getArg eval-p 0 F/Infinity)]
(ops-common/expr->double
(if (.isReal new-expr)
new-expr
(if (.isBuiltInSymbol arg0)
eval-p
arg0))))
(catch Exception e
(log/error "Error in evaling function on const xs vector: "
(str eval-p) " : " (.getMessage e))
(throw e))))


(defn eval-vec-pheno
"Evaluate a phenotype's expr on input xs/ys vecs"
[p
{:keys [input-xs-list input-xs-count input-ys-vec]
:as run-args}]
(let [^IExpr new-expr (:expr p)
^IExpr eval-p (eval-phenotype-on-expr-args p input-xs-list)]
(when-not (or (nil? eval-p) (= "Indeterminate" (str eval-p)))
(let [vs (mapv
(fn [i]
(try
(let [^IExpr res (.getArg eval-p (inc i) F/Infinity)]
(if (.isReal res)
(ops-common/expr->double res)
Double/POSITIVE_INFINITY))
(catch Exception e
(log/error "Error in evaling function on input values: " (str eval-p) " : " e)
Double/POSITIVE_INFINITY)))
(range (dec (.size eval-p))))
vs (if (= input-xs-count (count vs))
vs
(mapv
(fn [i]
(try
(let [^IExpr arg0 (.getArg eval-p 0 F/Infinity)]
(ops-common/expr->double
(if (.isReal new-expr)
new-expr
(if (.isBuiltInSymbol arg0)
eval-p
arg0))))
(catch Exception e
(log/error "Error in evaling function on const xs vector: "
(str eval-p) " : " (.getMessage e))
(throw e))))
(range input-xs-count)))]
vs))))
(when (parseable-eval-result? eval-p)
(mapv
(if (= input-xs-count (dec (.size eval-p)))
(partial result-args->doubles eval-p)
(partial result-args->constant-input eval-p new-expr))
(range input-xs-count)))))


(defn- clamp-oversampled-ys
Expand Down
118 changes: 59 additions & 59 deletions src/closyr/ops/initialize.clj
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@
:modifier-fn (fn ^IExpr [{^IAST expr :expr ^ISymbol x-sym :sym :as pheno}]
(F/Subtract expr (F/Divide 1 F/C10)))}

;; {:op :modify-fn
;; :label "+1/100"
;; :modifier-fn (fn ^IExpr [{^IAST expr :expr ^ISymbol x-sym :sym :as pheno}]
;; (F/Plus expr (F/Divide 1 F/C100)))}
;;
;; {:op :modify-fn
;; :label "-1/100"
;; :modifier-fn (fn ^IExpr [{^IAST expr :expr ^ISymbol x-sym :sym :as pheno}]
;; (F/Subtract expr (F/Divide 1 F/C100)))}
{:op :modify-fn
:label "+1/100"
:modifier-fn (fn ^IExpr [{^IAST expr :expr ^ISymbol x-sym :sym :as pheno}]
(F/Plus expr (F/Divide 1 F/C100)))}

{:op :modify-fn
:label "-1/100"
:modifier-fn (fn ^IExpr [{^IAST expr :expr ^ISymbol x-sym :sym :as pheno}]
(F/Subtract expr (F/Divide 1 F/C100)))}

{:op :modify-fn
:label "+Sin"
Expand Down Expand Up @@ -196,15 +196,15 @@
:modifier-fn (fn ^IExpr [{^IAST expr :expr ^ISymbol x-sym :sym :as pheno}]
(F/Times expr F/C10))}

;; {:op :modify-fn
;; :label "/100"
;; :modifier-fn (fn ^IExpr [{^IAST expr :expr ^ISymbol x-sym :sym :as pheno}]
;; (F/Times expr (F/Divide 1 F/C100)))}
;;
;; {:op :modify-fn
;; :label "*100"
;; :modifier-fn (fn ^IExpr [{^IAST expr :expr ^ISymbol x-sym :sym :as pheno}]
;; (F/Times expr F/C100))}
{:op :modify-fn
:label "/100"
:modifier-fn (fn ^IExpr [{^IAST expr :expr ^ISymbol x-sym :sym :as pheno}]
(F/Times expr (F/Divide 1 F/C100)))}

{:op :modify-fn
:label "*100"
:modifier-fn (fn ^IExpr [{^IAST expr :expr ^ISymbol x-sym :sym :as pheno}]
(F/Times expr F/C100))}

{:op :modify-fn
:label "*1.1"
Expand Down Expand Up @@ -251,20 +251,20 @@
(F/Divide (F/C1) ie)
ie))}

;; {:op :modify-leafs
;; :label "x/100"
;; :leaf-modifier-fn (fn ^IExpr [leaf-count {^IAST expr :expr ^ISymbol x-sym :sym :as pheno} ^IExpr ie]
;; (if (and (.isSymbol ie) (ops-common/should-modify-leaf leaf-count pheno))
;; (F/Divide ie (F/C100))
;; ie))}
;;
;;
;; {:op :modify-leafs
;; :label "100*x"
;; :leaf-modifier-fn (fn ^IExpr [leaf-count {^IAST expr :expr ^ISymbol x-sym :sym :as pheno} ^IExpr ie]
;; (if (and (.isSymbol ie) (ops-common/should-modify-leaf leaf-count pheno))
;; (F/Times ie (F/C100))
;; ie))}
{:op :modify-leafs
:label "x/100"
:leaf-modifier-fn (fn ^IExpr [leaf-count {^IAST expr :expr ^ISymbol x-sym :sym :as pheno} ^IExpr ie]
(if (and (.isSymbol ie) (ops-common/should-modify-leaf leaf-count pheno))
(F/Divide ie (F/C100))
ie))}


{:op :modify-leafs
:label "100*x"
:leaf-modifier-fn (fn ^IExpr [leaf-count {^IAST expr :expr ^ISymbol x-sym :sym :as pheno} ^IExpr ie]
(if (and (.isSymbol ie) (ops-common/should-modify-leaf leaf-count pheno))
(F/Times ie (F/C100))
ie))}

{:op :modify-leafs
:label "-1*x"
Expand Down Expand Up @@ -357,19 +357,19 @@
(F/Subtract ie (F/Divide 1 F/C10))
ie))}

;; {:op :modify-leafs
;; :label "x+1/100"
;; :leaf-modifier-fn (fn ^IExpr [leaf-count {^IAST expr :expr ^ISymbol x-sym :sym :as pheno} ^IExpr ie]
;; (if (and (.isSymbol ie) (ops-common/should-modify-leaf leaf-count pheno))
;; (F/Plus ie (F/Divide 1 F/C100))
;; ie))}
;;
;; {:op :modify-leafs
;; :label "x-1/100"
;; :leaf-modifier-fn (fn ^IExpr [leaf-count {^IAST expr :expr ^ISymbol x-sym :sym :as pheno} ^IExpr ie]
;; (if (and (.isSymbol ie) (ops-common/should-modify-leaf leaf-count pheno))
;; (F/Subtract ie (F/Divide 1 F/C100))
;; ie))}
{:op :modify-leafs
:label "x+1/100"
:leaf-modifier-fn (fn ^IExpr [leaf-count {^IAST expr :expr ^ISymbol x-sym :sym :as pheno} ^IExpr ie]
(if (and (.isSymbol ie) (ops-common/should-modify-leaf leaf-count pheno))
(F/Plus ie (F/Divide 1 F/C100))
ie))}

{:op :modify-leafs
:label "x-1/100"
:leaf-modifier-fn (fn ^IExpr [leaf-count {^IAST expr :expr ^ISymbol x-sym :sym :as pheno} ^IExpr ie]
(if (and (.isSymbol ie) (ops-common/should-modify-leaf leaf-count pheno))
(F/Subtract ie (F/Divide 1 F/C100))
ie))}

{:op :modify-leafs
:label "c/2"
Expand Down Expand Up @@ -428,20 +428,20 @@
(F/Divide F/C1 ie)
ie))}

;; {:op :modify-leafs
;; :label "c+1/100"
;; :leaf-modifier-fn (fn ^IExpr [leaf-count {^IAST expr :expr ^ISymbol x-sym :sym :as pheno} ^IExpr ie]
;; (if (and (.isNumber ie) (ops-common/should-modify-leaf leaf-count pheno))
;; (do
;; (F/Plus ie (F/Divide 1 F/C100)))
;; ie))}
;;
;; {:op :modify-leafs
;; :label "c-1/100"
;; :leaf-modifier-fn (fn ^IExpr [leaf-count {^IAST expr :expr ^ISymbol x-sym :sym :as pheno} ^IExpr ie]
;; (if (and (.isNumber ie) (ops-common/should-modify-leaf leaf-count pheno))
;; (F/Subtract ie (F/Divide 1 F/C100))
;; ie))}
{:op :modify-leafs
:label "c+1/100"
:leaf-modifier-fn (fn ^IExpr [leaf-count {^IAST expr :expr ^ISymbol x-sym :sym :as pheno} ^IExpr ie]
(if (and (.isNumber ie) (ops-common/should-modify-leaf leaf-count pheno))
(do
(F/Plus ie (F/Divide 1 F/C100)))
ie))}

{:op :modify-leafs
:label "c-1/100"
:leaf-modifier-fn (fn ^IExpr [leaf-count {^IAST expr :expr ^ISymbol x-sym :sym :as pheno} ^IExpr ie]
(if (and (.isNumber ie) (ops-common/should-modify-leaf leaf-count pheno))
(F/Subtract ie (F/Divide 1 F/C100))
ie))}

{:op :modify-leafs
:label "c+1/2"
Expand Down
33 changes: 17 additions & 16 deletions src/closyr/ops/modify.clj
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,17 @@
[:plus :times :divide12 :divide21 :minus12 :minus21])


(defn- check-modification-result
[max-leafs ^IExpr new-expr ^IExpr prev-expr]
(let [new-leafs (some-> new-expr (.leafCount))
new-is-invalid? (or (nil? new-leafs)
(nil? new-expr)
(> new-leafs max-leafs))
discount-mod? (or new-is-invalid?
(= (str prev-expr) (str new-expr)))]
[new-is-invalid? discount-mod?]))


(defn crossover
"Do phenotype crossover on their expr AST"
[max-leafs
Expand All @@ -150,12 +161,7 @@
:exp12 (F/Power e1-part e2-part)
:exp21 (F/Power e2-part e1-part))

new-leafs (some-> new-expr (.leafCount))
new-is-invalid? (or (nil? new-leafs)
(nil? new-expr)
(> new-leafs max-leafs))
discount-mod? (or new-is-invalid?
(= (str e1) (str new-expr)))]
[new-is-invalid? discount-mod?] (check-modification-result max-leafs new-expr e1)]

(if discount-mod?
;; keep last op:
Expand Down Expand Up @@ -185,7 +191,7 @@
mods []]
(if (zero? mods-left-to-apply)
{:new-pheno pheno :iters iters :mods mods}
(let [mod-to-apply (rand-nth initial-muts)
(let [mod-to-apply (rand-nth initial-muts)

;; get the util from the discard:
{^IExpr expr-prior :expr
Expand All @@ -205,17 +211,12 @@
" due to: " (or (.getMessage e) e)))
pheno))

new-leafs (some-> new-expr (.leafCount))
new-is-invalid? (or (nil? new-leafs)
(nil? new-expr)
(> new-leafs max-leafs))
discount-mod? (or new-is-invalid?
(= (str expr-prior) (str new-expr)))
[new-is-invalid? discount-mod?] (check-modification-result max-leafs new-expr expr-prior)

;; stop modification loop if too big or something went wrong:
count-to-go (if new-is-invalid?
0
(dec mods-left-to-apply))]
count-to-go (if new-is-invalid?
0
(dec mods-left-to-apply))]
(recur
;; count the mod only if expr actually changed and new mod is valid:
(if discount-mod? iters (inc iters))
Expand Down
19 changes: 8 additions & 11 deletions src/closyr/symbolic_regression.clj
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@

(go-loop [chart-iter 0]

(<! (timeout 50))
(<! (timeout 10))

(when-let [sim-msg (<! sim->gui-chan)]
(try
Expand Down Expand Up @@ -435,6 +435,8 @@

(defprotocol ISolverStateController

"Interface which allows creation and iteration of the symbolic regression GA solver"

(init
[this]
"Initialize solver state")
Expand Down Expand Up @@ -615,6 +617,8 @@

(defprotocol ISymbolicRegressionSolver

"A top-level interface to start the solver using CLI or GUI args"

(solve
[this]
"Run the solver on either CLI of GUI args. When using GUI, we block on getting a signal from the
Expand Down Expand Up @@ -660,22 +664,15 @@

(defn run-app-without-gui
"Run app without GUI and with fake placeholder input data"
[]
[xs ys]
(run-solver
{:initial-phenos (ops-init/initial-phenotypes 100)
:initial-muts (ops-init/initial-mutations)
:iters 20
:use-gui? false
:use-flamechart false
:input-xs-exprs (->> (range 50)
(map (fn [i] (* Math/PI (/ i 15.0))))
ops-common/doubles->exprs)
:input-ys-exprs (->> (range 50)
(map (fn [i]
(+ 2.0
(/ i 10.0)
(Math/sin (* Math/PI (/ i 15.0))))))
ops-common/doubles->exprs)}))
:input-xs-exprs (ops-common/doubles->exprs xs)
:input-ys-exprs (ops-common/doubles->exprs ys)}))


(defn- run-app-with-gui
Expand Down
2 changes: 1 addition & 1 deletion src/closyr/ui/gui.clj
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@
brush-label:line sketchpad-on-click:line-brush})


(def selectable-input-fns
(def ^:private selectable-input-fns
(input-data/input-y-fns-data sketchpad-size* sketch-input-x-count*))


Expand Down
Loading

0 comments on commit a75b922

Please sign in to comment.