Skip to content

Commit

Permalink
More Schemas (#10)
Browse files Browse the repository at this point in the history
* more schema

* more schema

* more schema

* more schema

* more schema

* more schema

* more schema

* test cases
  • Loading branch information
ogeagla authored Feb 16, 2024
1 parent c3d83a2 commit 96a3815
Show file tree
Hide file tree
Showing 13 changed files with 154 additions and 60 deletions.
4 changes: 2 additions & 2 deletions src/closyr/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
(:require
[clojure.string :as str]
[clojure.tools.cli :as cli]
[closyr.symbolic-regression :as symreg]
[closyr.util.csv :as input-csv]
[closyr.util.log :as log]
[closyr.symbolic-regression :as symreg])
[closyr.util.log :as log])
(:import
(java.io
File)))
Expand Down
26 changes: 18 additions & 8 deletions src/closyr/ops.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
(:require
[clojure.core.async :as async :refer [go go-loop timeout <!! >!! <! >! chan put! take! alts!! alts! close!]]
[clojure.string :as str]
[closyr.util.prng :refer :all]
[closyr.util.log :as log]
[closyr.ops.common :as ops-common]
[closyr.ops.eval :as ops-eval]
[closyr.ops.modify :as ops-modify]
[closyr.util.log :as log]
[closyr.util.prng :refer :all]
[closyr.util.spec :as specs])
(:import
(java.text
Expand Down Expand Up @@ -95,7 +95,9 @@
(* (abs score) (min 0.1 (* 0.0000001 leafs leafs))))


(defn- compute-score-from-actuals-and-expecteds
(defn compute-score-from-actuals-and-expecteds
"Compute overall score for fn given some actual and expected ys"
{:malli/schema [:=> [:cat #'specs/GAPhenotype [:vector number?] [:vector number?] number?] number?]}
[pheno f-of-xs input-ys-vec leafs]
(try
(let [abs-resids (map compute-residual input-ys-vec f-of-xs)
Expand All @@ -116,8 +118,8 @@

(defn score-fn
"Symbolic regression scoring"
[{:keys [input-xs-list input-xs-count input-ys-vec
sim-stop-start-chan sim->gui-chan]
{:malli/schema [:=> [:cat #'specs/ScoreFnArgs [:map {:closed false} [:max-leafs number?]] #'specs/GAPhenotype] number?]}
[{:keys [input-xs-list input-xs-count input-ys-vec]
:as run-args}
{:keys [max-leafs]}
pheno]
Expand All @@ -141,6 +143,13 @@

(defn mutation-fn
"Symbolic regression mutation"
{:malli/schema
[:=>

[:cat [:map {:closed false} [:max-leafs number?]] [:sequential #'specs/GAMutation] #'specs/GAPhenotype #'specs/GAPhenotype]

#'specs/GAPhenotype]}

[{:keys [max-leafs]}
initial-muts
p-winner
Expand All @@ -164,13 +173,14 @@

(assoc new-pheno :mods-applied iters))
(catch Exception e
(log/error "Err in mutation: " (or (.getMessage e) e)))))
(log/error "Err in mutation: " (or (.getMessage e) e))
(assoc p-winner :util (:util p-discard)))))


(defn crossover-fn
"Symbolic regression crossover"
[{:keys [max-leafs]
:as run-args}
:as run-config}
initial-muts
p
p-discard]
Expand All @@ -179,7 +189,7 @@
(swap! sim-stats* update-in [:crossovers :counts] #(inc (or % 0))))
(or
crossover-result
(mutation-fn run-args initial-muts p p-discard))))
(mutation-fn run-config initial-muts p p-discard))))


(defn- sort-population
Expand Down
2 changes: 1 addition & 1 deletion src/closyr/ops/common.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
(:refer-clojure :exclude [rand rand-int rand-nth shuffle])
(:require
[clojure.core.async :as async :refer [go go-loop timeout <!! >!! <! >! chan put! take! alts!! alt!! close!]]
[closyr.util.prng :refer :all]
[closyr.util.log :as log]
[closyr.util.prng :refer :all]
[closyr.util.spec :as specs])
(:import
(java.util
Expand Down
2 changes: 1 addition & 1 deletion src/closyr/ops/eval.clj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(ns closyr.ops.eval
(:require
[closyr.util.log :as log]
[closyr.ops.common :as ops-common]
[closyr.util.log :as log]
[closyr.util.spec :as specs])
(:import
(org.matheclipse.core.eval
Expand Down
2 changes: 1 addition & 1 deletion src/closyr/ops/initialize.clj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(ns closyr.ops.initialize
(:require
[closyr.util.log :as log]
[closyr.ops.common :as ops-common]
[closyr.util.log :as log]
[closyr.util.spec :as specs])
(:import
(org.matheclipse.core.expression
Expand Down
2 changes: 1 addition & 1 deletion src/closyr/ops/modify.clj
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
#'specs/GAPhenotype]

;; outputs:
#'specs/GAPhenotype]}
[:maybe #'specs/GAPhenotype]]}
[max-leafs
{^IAST e1 :expr ^ISymbol x-sym :sym ^ExprEvaluator util :util :as p}
{^IAST e2 :expr :as p-discard}]
Expand Down
14 changes: 8 additions & 6 deletions src/closyr/symbolic_regression.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
(:require
[clojure.core.async :as async :refer [go go-loop timeout <!! >!! <! >! chan put! take! alts!! alts! close!]]
[closyr.ga :as ga]
[closyr.util.log :as log]
[closyr.ops :as ops]
[closyr.ops.common :as ops-common]
[closyr.ops.initialize :as ops-init]
[closyr.util.spec :as specs]
[closyr.ui.gui :as gui]
[closyr.util.log :as log]
[closyr.util.spec :as specs]
[flames.core :as flames]
[malli.core :as m]
[seesaw.core :as ss])
Expand Down Expand Up @@ -355,7 +355,9 @@
nil))))))))


(defn- ->run-args
(defn ->run-args
"Generate one-time computed args for solver"
{:malli/schema [:=> [:cat map?] #'specs/SolverRunArgs]}
[{input-xs-exprs :input-xs-exprs
input-xs-vec :input-xs-vec
input-ys-vec :input-ys-vec
Expand Down Expand Up @@ -468,8 +470,8 @@

(init
[this]
(specs/validate! "SolverRunConfig" specs/SolverRunConfig run-config)
(specs/validate! "SolverRunArgs" specs/SolverRunArgs run-args)
(specs/validate! "SolverRunConfig" #'specs/SolverRunConfig run-config)
(specs/validate! "SolverRunArgs" #'specs/SolverRunArgs run-args)
(let [{:keys [iters initial-phenos initial-muts use-gui?]} run-config
start (print-and-save-start-time iters initial-phenos)
init-pop (ga/initialize
Expand Down Expand Up @@ -499,7 +501,7 @@
:final-population population
:next-step :wait})
(let [{scores :pop-scores :as ga-result} (ga/evolve population)]
(specs/validate! "GAPopulation" specs/GAPopulationPhenotypes (:pop ga-result))
(specs/validate! "GAPopulation" #'specs/GAPopulationPhenotypes (:pop ga-result))
(ops/report-iteration iters-to-go iters ga-result run-args run-config)
(assoc this :ga-result ga-result :iters-to-go (next-iters iters-to-go scores)))))))

Expand Down
4 changes: 2 additions & 2 deletions src/closyr/ui/gui.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
(:require
[clojure.core.async :as async :refer [go go-loop timeout <!! >!! <! >! chan put! alts!]]
[clojure.java.io :as io]
[closyr.util.csv :as input-csv]
[closyr.dataset.inputs :as input-data]
[closyr.util.log :as log]
[closyr.ui.plot :as plot]
[closyr.util.csv :as input-csv]
[closyr.util.log :as log]
[seesaw.behave :as sb]
[seesaw.border :as sbr]
[seesaw.core :as ss]
Expand Down
44 changes: 26 additions & 18 deletions src/closyr/util/spec.clj
Original file line number Diff line number Diff line change
Expand Up @@ -32,33 +32,33 @@


#_(defn- disable-validate-instrumentation!
"Turn off all schema checks"
[]
(alter-var-root #'*check-schema* (constantly false))
(mi/unstrument!
{:filters [(apply mi/-filter-ns (concat (keys (m/function-schemas))
['closyr.util.spec-test
'cursive.tests.runner
'user]))]}))
"Turn off all schema checks"
[]
(alter-var-root #'*check-schema* (constantly false))
(mi/unstrument!
{:filters [(apply mi/-filter-ns (concat (keys (m/function-schemas))
['closyr.util.spec-test
'cursive.tests.runner
'user]))]}))


(def GAPhenotype
(def ^:private GAPhenotype
[:map
{:closed true}
[:id {:optional true} :uuid]
[:sym some?]
[:expr {:optional true} any?]
[:expr {:optional true} some?]
[:score {:optional true} number?]
[:util {:optional true} any?]
[:last-op {:optional true} :string]
[:mods-applied {:optional true} :int]])


(def GAPopulationPhenotypes
(def ^:private GAPopulationPhenotypes
[:vector #'GAPhenotype])


(def GAMutation
(def ^:private GAMutation
[:map
{:closed true}
[:op :keyword]
Expand All @@ -69,7 +69,7 @@
[:replace-expr {:optional true} some?]])


(def SolverRunConfig
(def ^:private SolverRunConfig
[:map
{:closed true}
[:iters pos-int?]
Expand All @@ -84,30 +84,38 @@
[:input-ys-exprs [:sequential some?]]])


(def SolverRunArgs
(def ^:private SolverRunArgs
[:map
{:closed true}
[:sim->gui-chan {:optional true} some?]
[:sim-stop-start-chan {:optional true} some?]
[:extended-domain-args map?]
[:input-xs-list some?]
[:input-xs-count pos-int?]
[:input-xs-vec [:vector double?]]
[:input-ys-vec [:vector double?]]
[:input-xs-vec [:vector number?]]
[:input-ys-vec [:vector number?]]
[:input-iters pos-int?]
[:initial-phenos [:maybe [:sequential map?]]]
[:input-phenos-count [:maybe pos-int?]]
[:max-leafs [:maybe pos-int?]]])


(def SolverEvalArgs
(def ^:private SolverEvalArgs
[:map
{:closed false}
[:input-xs-list some?]
[:input-xs-count pos-int?]])


(def ^:private ScoreFnArgs
[:map
{:closed false}
[:input-ys-vec [:vector number?]]
[:input-xs-list some?]
[:input-xs-count pos-int?]])


(def SolverRunResults
(def ^:private SolverRunResults
[:map
{:closed true}
[:iters-done number?]
Expand Down
20 changes: 18 additions & 2 deletions test/closyr/ops_modify_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
(:require
[clojure.core.async :as async :refer [go go-loop timeout <!! >!! <! >! chan put! take! alts!! alt!! close!]]
[clojure.test :refer :all]
[closyr.util.prng :as prng]
[closyr.ops.common :as ops-common]
[closyr.ops.initialize :as ops-init]
[closyr.ops.modify :as ops-modify])
[closyr.ops.modify :as ops-modify]
[closyr.util.prng :as prng])
(:import
(org.matheclipse.core.expression
F)
Expand Down Expand Up @@ -383,6 +383,22 @@
:expr (F/Plus x (F/Times x (F/Cos (F/Subtract x F/C1D2))))})))
(str F/C4))))))))


(with-redefs-fn {#'prng/rand-int (fn [maxv] (dec maxv))
#'prng/rand-nth (fn [coll] (last coll))
#'ops-modify/check-modification-result (fn [_ _ _] (throw (Exception. "Test exception")))}
(fn []
(with-redefs [ops-modify/crossover-sampler [:times]]
(let [x (F/Dummy "x")]
(testing "Crossover failure"
(is (= (ops-modify/crossover
100
{:sym x
:expr F/C4}
{:sym x
:expr (F/Plus x (F/Times x (F/Cos (F/Subtract x F/C1D2))))})
nil)))))))

(with-redefs-fn {#'prng/rand-int (fn [maxv] (dec maxv))
#'prng/rand-nth (fn [coll] (last coll))}
(fn []
Expand Down
Loading

0 comments on commit 96a3815

Please sign in to comment.