Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More Code Style / Disable PR CI tests #7

Merged
merged 10 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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