Fork me on GitHub
#data-science
<
2023-04-27
>
geoff09:04:48

Anyone know of a generic optimisation library for clojure? I want the equivalent of a data solver like in excel

geoff09:04:14

Some sort of convex optimisation or gradient decent thing, I’m ignorant about how they work

geoff10:04:11

Very nice, thanks

genmeblog10:04:51

Let me know if you hit any problems (some things can be tricky, also avoid `:bfgs` which is buggy)

geoff10:04:54

Is this able to optimise to a specific value? Or would you like wrap the desired function in another one where the desired value is a minimum or something?

geoff10:04:40

To answer questions like, find a set of values x y … such that f(x,y,..) = 3838 or something

genmeblog10:04:07

generally optimizers search for minimum/maximum, so there is no option to find a specific value

genmeblog10:04:35

for your case you should reach for solver, however there is only univariate one. Checking if it's possible to make multivariate solver (I rely on Apache Commons Math)

geoff10:04:36

thats good to know

geoff10:04:12

made a little wrapper function that defines the squared error of a value function from a value that seems to work for what i needed when minimising

``````(fn [j v]
(fn [& rst]
(let [error (- (apply j rst) v)]
(* error error))))``````

👍 2
geoff10:04:58

this is fun, thanks again

genmeblog10:04:11

great! yeah, that's one of the aproaches.

respatialized13:04:47

> To answer questions like, find a set of values x y … such that f(x,y,..) = 3838 or something for satisfiability problems like these there are other options, which, owing to the intrinsic computational complexity of these problems, will be much slower than gradient descent because they look for exact solutions • https://github.com/clojure/core.logichttps://github.com/Engelberg/rolling-stoneshttps://torvaney.github.io/projects/flow-solver.html

mlimotte14:04:53

Google OR-Tools maybe: https://developers.google.com/optimization It’s java, but you can wrap it with Clojure. I did for my purposes.

Aziz Aldawood05:04:34

It's not hard to write your own root finder. I think excel uses a variation of newton-raphson method. here is my code

``````(ns aziz.newton
(:require [clojure.math :as math]))

(defn newton-raphson
[f f-derivative x0 tolerance max-iterations]
(loop [x x0
x_prev (+ x0 0.0001)
iterations 0]
(let [fx (f x)
fpx (f-derivative x x_prev)
x1 (- x (/ fx fpx))
error (Math/abs (- x1 x))]
(if (or (< error tolerance) (>= iterations max-iterations))
x1
(recur x1 x (inc iterations))))))

(defn f
"this is the function we want to find the root of, g need to be defined in a way that g(x)=0.
for example, to calculate xirr, we need to define npv function such that x is the rate of return and
npv(x) = 0"
[g guess]
(g guess))

(defn f'
[g guess previous-guess]
(/ (- (g guess) (g previous-guess)) (- guess previous-guess)))

(comment
(defn fun [x]
(- x (math/pow 48 (/ 1 3))))

(newton-raphson fun (partial f' fun) 1 0.0001 1000))``````
in your example of f(x,y,..) = 3838, you convert it into f(x,y,..) - 3838 = 0 I wrote this for a quick side analysis that I needed and I didn't know the libraries mentioned above

genmeblog06:04:18

I understand that we speak about multivariate case here.

Aziz Aldawood07:04:01

oh yes you're right, my solution is not good

geoff07:04:43

these look great, particularly OR-Tools, thanks again

mlimotte18:05:30

@U01MV1EPVK8 Let me know how OR-Tools works for you. I had some fun, writing Clojure wrappers for the CP-SAT Solver, to support linear expressions in data structures. See https://docs.google.com/presentation/d/1YD1qHaSveI58gFHoe-pc3c9fQMn9cCwYnSW9XjeeF4o/edit#slide=id.g13f7fc68ac4_0_5 (ignore the DSL approach-- I don’t like it): TL:DR

``````(let [domain {"x" [:range 0 20]
"y" [:range 0 20]}
eqs2   [
["=" ["y"] [[2 "x"] 3]]       ; y = 2x + 3
["<" ["x"] [4]]               ; (x < 4)
]]
(q/solve-equations domain eqs2))``````

geoff09:04:56

It’s called goal-seek in excel, or this plugin: https://www.solver.com/excel-solver-how-load-or-start-solver