Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Jo
Jan 24, 2005

:allears:
Soiled Meat
I'm going to harken back to the Sieve of Eratosthenes question from page 4.

I'm starting to fiddle with Clojure (I'd started in Racket but didn't like the docs). One of my biggest motivations was being able to more simply implement symbolic differentiation and machine learning stuff. The tricky part with that is I'm generally only familiar with the cases where you have really big matrices which are updated a whole bunch of times. I've heard Clojure keeps around old references, and that worries me. I know they don't use copy-on-write, but something more efficient. All the same, when you've got structures that don't fit into memory and require dozens of updates, it makes me a little concerned about how that's going to work out in a purely functional language, or if it's not objectionable to have side-effects by design. Does the matrix become the mutable state of the application?

Adbot
ADBOT LOVES YOU

Jo
Jan 24, 2005

:allears:
Soiled Meat

Tequila Bob posted:

Clojure is totally cool with your mutable state. If you want to mutate a huge matrix while using idiomatic code, I'd recommend that you use "transients" (http://clojure.org/reference/transients). Clojure's vectors are capable of transient operations, so you should be able to represent your matrix as a transient vector of transient vectors. You can code like it's Clojure and consume memory like it's imperative code manipulating one global blob of memory!

There are also matrix libraries you could look at, like https://github.com/mikera/core.matrix. I have no experience with it, but you might take a look.

Finally, I suggest that you not worry about memory consumption before writing the code. Instead, I think you should write your code first, then determine if it's too slow or too memory-heavy, and then consider ways to deal with it. Unless you've already written some code and observed a memory problem, you are currently engaged in premature optimization.

I had no idea about transients! That seems to be precisely what I need. It's going to take me a while to figure out how to re-fit my mental model of the problem to use them, but I'm thinking that will handle it.

I've been bitten by memory consumption problems with this problem domain before, so I'm always on the lookout. Our production server has 128 gigs of ram and I'm still bumping up against that limit when I run the application full tilt. I'd love to get utilization down, but there's only so much that you can do when you've got a giant multi-gigabyte matrix that you're constantly rebuilding.

EDIT: Follow-up question because I don't want to bump.

I wrote a simple automatic differentiation method and was wondering about a certain operator comparison.

code:
(require 'clojure.walk)

(defn grad 
	[f wrt]
	(cond
		(keyword? f) (if (= f wrt) 1 0)
		(number? f) 0
		(seq? f) (let [op (first f), params (rest f)] 
			(cond
				(or (= op 'clojure.core/+) (= op '+)) `(+ ~@(map #(grad % wrt) params))
				(or (= op 'clojure.core/*) (= op '*)) `(+ (* ~(grad (first params) wrt) ~(second params)) (* ~(first params) ~(grad (second params) wrt)))
				:else (print "poo poo"))
			)
		:else (print "gently caress")
	)
)

(defn eval-fun [fun varmap] (eval (clojure.walk/postwalk-replace varmap fun)))
(defn eval-grad [fun varmap wrt] (eval (clojure.walk/postwalk-replace varmap (grad fun wrt))))
I'm pleased with how small it is, but the operator comparison (or (= op 'clojure.core/+) (= op '+)) looks messy to me.

Is there a consistent way to check operators? Sometimes they seem to go to clojure.core/+, sometimes to +, and sometimes to #<native method blah blah.>

Jo fucked around with this message at 23:48 on Mar 10, 2016

Jo
Jan 24, 2005

:allears:
Soiled Meat
I think I had heard of Elm a while back and it looks like a nice alternative to writing JavaScript. I've got some reservations about it, mostly related to what looks like mixing of styling and code in their examples. Has anyone styled an Elm app with CSS on top of their HTML generation?

  • Locked thread