Wesley R. Elsberry
Posts: 4991 Joined: May 2002
|
While I was looking up use of PyQtGraph in PySide, I ran across an example program in an unfamiliar language. A little probing led me to the website for Julia, a new (2013 FOSS release) programming language for scientific and technical computing. The language is dynamic, but uses just-in-time (JIT) compiler technology to achieve benchmark tests within 2x the time C code takes. There's an IDE, Julia Studio, that I am finding useful. Emacs and the command line work just fine as well.
As an initial exercise, I ported my "minimal weasel" program from Python to Julia. The result is a 46-line program. This is slightly longer than the Python version because I'm using a line each for the Julia convention of closing a block with "end". Python uses indentation to indicate block closure.
Code Sample | # Minimum Weasel in Julia -- Wesley R. Elsberry t = "METHINKS IT IS LIKE A WEASEL" # Target phrase b = " ABCDEFGHIJKLMNOPQRSTUVWXYZ" # Base pool n = 178 # Population size u = (1.0 / length(t)) # Mutation rate @printf("Popsize=%d, Mutrate=%f, Bases=%s, Target=%s\n", n,u,b,t) p = "" # Parent string for ii in [1:length(t)] # Compose random parent string p = p * string(b[rand(1:length(b))]) end @printf(" Parent=%s\n",p) done = false # Loop control variable g = 0 # Generation counter bmcnt = 0 # Base match count (max. in pop.) bc = "" # Best candidate variable while (done == false) pop = ASCIIString[] # Population of strings bmcnt = 0 # Start with no bases matched bcindex = 1 # Point to first candidate in pop. by default for ii in [1:n] # For size of population push!(pop,"") # Add an empty candidate mcnt = 0 # Initialize candidate base match count to zero for jj in [1:length(t)] # Compose a new candidate possibly mutated from the parent if u >= rand() # We have a mutated base pop[ii] = pop[ii][1:jj-1] * string(b[rand(1:length(b))]) else # No mutation, just copy this base pop[ii] = pop[ii][1:jj-1] * string(p[jj]) end if pop[ii][jj] == t[jj] # Candidate matches target at this base mcnt += 1 # Increment candidate base match count end if mcnt > bmcnt # Candidate is better than current best match bmcnt = mcnt # Change best match count bcindex = ii # Store index of best candidate end if mcnt >= (length(t) - 0) # Do enough bases match the target? done = true # Yes, so set loop control for exit end end end bc = pop[bcindex] # Set best candidate as candidate at index g += 1 # Increment generation count @printf("Gen=%05d, %02d/%d matched, Best=%s, Total=%06d\n", g, bmcnt, length(t), bc, g*n) p = bc # Parent for next generation is the best candidate from this one end println("weasel done.")
|
There are a few noteworthy differences from Python. First, Julia is a base-1 language. Arrays start with index 1. Second, Julia's dynamic variable creation requires that a type be provided for declaration of empty arrays. Julia can figure out the type itself for an array that is assigned at least one element, but the programmer has to give a type in order to start with no elements at all. The type system in Julia is apparently one big reason why the developers are able to obtain the good benchmark results. Third, while I have not taken advantage of it here, Julia's syntax allows for expressions to be closer to mathematical notation. "1 + 2x" in Julia is legal, where in Python one would have to have, "1 + 2*x".
I'm planning on porting a more complex program to Julia to see how it performs compared to PyPy.
-------------- "You can't teach an old dogma new tricks." - Dorothy Parker
|