Wednesday, August 1, 2012

Trying Julia

In my previous post I tried building Williams designs in R. Since that code was running a bit slow, this was an ideal test for Julia. Big enough to be at least slightly realistic, small enough that it is doable.
I am very impressed. Almost twenty fold speed increase, even though this was the best I could do in R, the most naive way possible in Julia.
                                       R              Julia        Ratio
Double Williams design 4, 100 times    3.97 sec       0.212 sec    0.053   
Williams design 5, 10 times          289.5 sec       18.54  sec    0.064 


I'd surely love to use Julia more. For instance, if I could port some of the algorithm's of Professor Ng Machine Learning class to Julia? I don't think it is possible yet, but what is not, may come.

Julia code

macro timeit(ex,name,num)
    quote
        t0 = 0
        for i=1:$num
            t0 = t0 + @elapsed $ex
        end
        println("julia,", $name, ",", t0)
        #gc()
    end
end


function gendesign(ncol)
  nrow=ncol*2
  desmat = zeros(Uint8,nrow,ncol)
  desmat[1,1:ncol] = [1:ncol]
  for i = [1:ncol]
    desmat[2*i-1,1] = i
    desmat[2*i,1]=i
  end
  carover = zeros(Uint8,ncol,ncol)
  for i = 1:(ncol-1)
    carover[i,i+1] = 1
  end
  count   = 0
  addpoint( desmat , carover,count)
end

function numzero(matin) 
  length(matin) - nnz(matin) 
end   
 
function first0(matin)
   if numzero(matin)==0
      return -1
   end   
   nrow, ncol = size(matin)
   for row = 1:nrow
      for col = 1:ncol
         if matin[row,col] == 0
            return row, col
         end
      end
    end   
end   

function addpoint(desmat,carover,count)
  if nnz(desmat) == length(desmat)
     count +=1
     print("x")
     return count
  end
  row,col  = first0(desmat)
  for i = [1:size(desmat,2)]
     if numzero(desmat[row,:]-i) == 0
        if numzero(desmat[:,col]-i) < 2
           if carover[desmat[row,col-1],i] < 2 
              if (col !=2) | (desmat[row,1] != desmat[row-1,1]) | (desmat[row-1,col] < i)
                 desmat[row,col]=i
                 carover[desmat[row,col-1],i] +=1
                 count = addpoint(desmat,carover,count)
                 desmat[row,col]=0
                 carover[desmat[row,col-1],i] -=1
              end
            end 
         end 
      end 
   end 
   return count
end

@timeit gendesign(4) "design 4 " 100
@timeit gendesign(5) "design 5 " 10

Note

Both designs were created using the same script. If you ask an even number of design points using the odd algorithm, then this will work. You just get a design with double the rows, carry over balanced, every treatment equally often in each row and each column.

No comments:

Post a Comment