I had some problems with "typed" ragged arrays when I tried to wrap Lib-linear in Clojure. Kevin Lynagh and Benedikt Waldvogel had already solved them in clj-liblinear, thanks!
Now onto some batching for determining nice parameters for our tests.
måndag 3 juni 2013
tisdag 28 maj 2013
Quick distinct set generator
In one application I needed to create quite many sets of distinct numbers in a limited range.
This is done quickly by doing a knuth-shuffle of an array with all the numbers in the range and do the random swapping as many steps as the size of the requested set.
Here's a typed and thread safe version - no reflections gives a super quick execution. The locking macro makes sure we don't mix everything up by parallel threads.
(let [vektor-length 400
set-size 20
shuffle-seed (long-array (shuffle (range vektor-length)))]
(defn shuffle-n!
"swaps the n first with any other in vector,
(see knuth shuffle)
array locking has to be done by the caller, otherwise
we could have leaks -> duplicates"
[^longs arr n]
(dotimes [idx n]
(let [shuffle-with-idx (rand-int vektor-length)
a (aget arr idx)
b (aget arr shuffle-with-idx)]
(aset arr idx b)
(aset arr shuffle-with-idx a))))
(defn gen-distinct-set []
(locking ^longs shuffle-seed
(shuffle-n! shuffle-seed set-size)
(let [new-distinct-set (long-array set-size)]
(dotimes [idx set-size]
(aset new-distinct-set idx (aget ^longs shuffle-seed idx)))
new-distinct-set))))
A test of this algorithm rendered a million sets in less than a second, which was more than sufficient for my application, otherwise my next step would have been to dig into thread-local constructs in flatland/useful thread-local macro, where every thread could have it's own seed vector.
(I don't check for duplicates, since they are unlikely enough for my application).
This is done quickly by doing a knuth-shuffle of an array with all the numbers in the range and do the random swapping as many steps as the size of the requested set.
Here's a typed and thread safe version - no reflections gives a super quick execution. The locking macro makes sure we don't mix everything up by parallel threads.
(let [vektor-length 400
set-size 20
shuffle-seed (long-array (shuffle (range vektor-length)))]
(defn shuffle-n!
"swaps the n first with any other in vector,
(see knuth shuffle)
array locking has to be done by the caller, otherwise
we could have leaks -> duplicates"
[^longs arr n]
(dotimes [idx n]
(let [shuffle-with-idx (rand-int vektor-length)
a (aget arr idx)
b (aget arr shuffle-with-idx)]
(aset arr idx b)
(aset arr shuffle-with-idx a))))
(defn gen-distinct-set []
(locking ^longs shuffle-seed
(shuffle-n! shuffle-seed set-size)
(let [new-distinct-set (long-array set-size)]
(dotimes [idx set-size]
(aset new-distinct-set idx (aget ^longs shuffle-seed idx)))
new-distinct-set))))
A test of this algorithm rendered a million sets in less than a second, which was more than sufficient for my application, otherwise my next step would have been to dig into thread-local constructs in flatland/useful thread-local macro, where every thread could have it's own seed vector.
(I don't check for duplicates, since they are unlikely enough for my application).
tisdag 26 mars 2013
Don'ts: Git hooks as CI/deploy tool
GIҬ
I want to get Heroku-like functionality for deploying new version - just git push and you're done. Crazy sexy cool.
I did try with git hooks in various ways, but since I run the server as a nohup jetty-process (I know) and have to kill that in brutal ways, cannot be sure on the merging of the branches since I had the git repo checked out (use a intermediate bare repo, please) I could not get it work. It was also really hard to know what was happening.
The search light is now against lein-war (for running in tomcat7) and some nice pallet solution.\
Git hooks is awesome for other things, but they are no system deployment/ continuous integration tool.
Update: I'm now a happy Jenkins user. Easy to get started with!
fredag 22 mars 2013
merge-with to the rescue
I'm working on coloring a map with different colors, that sometimes overlap.
After deep though I found out that I could have colorings in maps and then merge the maps somehow. This doesn't work perfectly, but it's a good start. After fiddling around with home-brewed solutions I looked in core.clj for merge in the source code and found merge-with just below. Perfect match.
A short example of the power of merge-with:
(def scandinavia (zipmap ["sweden" "norway" "denmark" "aaland" "iceland" "finland" "greenland" "fareoes"] (repeat :yellow)))
=>{"fareoes" :yellow, ...
(def swedish-speaking (zipmap ["sweden" "aeland" "finland" "ukraine" ] (repeat :red)))
=>{"ukraine" :red, ... * see below for Swedish language in Ukraine
(defn blend [a b] :orange)
(merge-with blend scandinavia swedish-speaking)
{"ukraine" :red,
"fareoes" :yellow,
"greenland" :yellow,
"finland" :orange,
"iceland" :yellow,
"aaland" :orange,
"denmark" :yellow,
"norway" :yellow,
"sweden" :orange}
As you can I cheated quite extensively with the blend function, but in this case it doesn't matter, since we're always blending yellow and red if we are blendning.
Merge-with uses the function given (blend) if two keys are colliding when merging. If you want to sum to maps, use (merge-with + {:x 1 :y 2} {:x 3}) and get {:x 4 :y 2}.
* And yes, there are some really old ladies speaking Swedish in Ukraine in the Gammalsvenskby.
After deep though I found out that I could have colorings in maps and then merge the maps somehow. This doesn't work perfectly, but it's a good start. After fiddling around with home-brewed solutions I looked in core.clj for merge in the source code and found merge-with just below. Perfect match.
A short example of the power of merge-with:
(def scandinavia (zipmap ["sweden" "norway" "denmark" "aaland" "iceland" "finland" "greenland" "fareoes"] (repeat :yellow)))
=>{"fareoes" :yellow, ...
(def swedish-speaking (zipmap ["sweden" "aeland" "finland" "ukraine" ] (repeat :red)))
=>{"ukraine" :red, ... * see below for Swedish language in Ukraine
(defn blend [a b] :orange)
(merge-with blend scandinavia swedish-speaking)
{"ukraine" :red,
"fareoes" :yellow,
"greenland" :yellow,
"finland" :orange,
"iceland" :yellow,
"aaland" :orange,
"denmark" :yellow,
"norway" :yellow,
"sweden" :orange}
As you can I cheated quite extensively with the blend function, but in this case it doesn't matter, since we're always blending yellow and red if we are blendning.
Merge-with uses the function given (blend) if two keys are colliding when merging. If you want to sum to maps, use (merge-with + {:x 1 :y 2} {:x 3}) and get {:x 4 :y 2}.
* And yes, there are some really old ladies speaking Swedish in Ukraine in the Gammalsvenskby.
torsdag 21 mars 2013
Minimal C2 bind! example
C2 is a very sane vizualisation library for both Clojure and ClojureScript.
I had a hard time grasping bind! and unify, so I wanted to make the smallest example I could think of: generate a blue svg circle.
From O'Reilly's excellent introduction to SVG (available online) I found that the XML for an SVG circle would be something like:
<svg width="400px" height="400px">
<circle cx="100" cy="100" r="45" style="fill: 'blue';"/>
</svg>
I did once spend unreasonably long time to try to reach the DOM of an embedded SVG image, so from now on I embed the SVG DOM root in my html document, like this document with an empty SVG tag with id "bubbles":
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SVG bubble</title>
</head>
<body>
<div>
<svg id="bubbles"></svg></div>
</div>
<script src="/cljscode.js"></script>
</body>
</html>
C2 transforms tags like Hiccup do, but you can say where you want to add it with the macro c2.util/bind! (works a bit like in enlive).
And some very minimal ClojureScript code:
(ns c2test.core
(:require [c2.core :as c2core])
(:require-macros [c2.util :as c2util]))
(defn ^:export c2bubble [x y r]
(c2util/bind! "#bubbles"
[:svg#bubbles {:style {:display "block" :margin "auto" :height 200 :width 200}}
[:circle {:cx x :cy y :r r :style { :fill "blue"}}]]))
By opening a browser console (for javascript) I can set coordinates of a blue bubble with a command like
c2test.core.c2bubble(20,50,30);
Now on to world domination.
I had a hard time grasping bind! and unify, so I wanted to make the smallest example I could think of: generate a blue svg circle.
From O'Reilly's excellent introduction to SVG (available online) I found that the XML for an SVG circle would be something like:
<svg width="400px" height="400px">
<circle cx="100" cy="100" r="45" style="fill: 'blue';"/>
</svg>
I did once spend unreasonably long time to try to reach the DOM of an embedded SVG image, so from now on I embed the SVG DOM root in my html document, like this document with an empty SVG tag with id "bubbles":
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SVG bubble</title>
</head>
<body>
<div>
<svg id="bubbles"></svg></div>
</div>
<script src="/cljscode.js"></script>
</body>
</html>
C2 transforms tags like Hiccup do, but you can say where you want to add it with the macro c2.util/bind! (works a bit like in enlive).
And some very minimal ClojureScript code:
(ns c2test.core
(:require [c2.core :as c2core])
(:require-macros [c2.util :as c2util]))
(defn ^:export c2bubble [x y r]
(c2util/bind! "#bubbles"
[:svg#bubbles {:style {:display "block" :margin "auto" :height 200 :width 200}}
[:circle {:cx x :cy y :r r :style { :fill "blue"}}]]))
By opening a browser console (for javascript) I can set coordinates of a blue bubble with a command like
c2test.core.c2bubble(20,50,30);
Now on to world domination.
onsdag 20 mars 2013
Logging in Clojure
There are several competing logging facilities in Java and some custom made for Clojure.
If you are starting a new project, consider to simply use Logback. There's an bloggpost introduction to integrate logback with Clojure and it's github repo clojure-example-logback-integration.
This took me too long to figure out.
If you are starting a new project, consider to simply use Logback. There's an bloggpost introduction to integrate logback with Clojure and it's github repo clojure-example-logback-integration.
This took me too long to figure out.
måndag 19 mars 2012
[] and {} revealed!
These are good explanations of PersistentVector and PersistentHashmap. Read them now, if you are the least unsure on how the [] and {} works!
Prenumerera på:
Inlägg (Atom)
