Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0

Showing posts with label functional code. Show all posts
Showing posts with label functional code. Show all posts

Monday, 10 March 2014

Yet Another Nature of Code Example ported to ruby-processing

For the nn library java code see ruby-processing on github.
# The Nature of Code
# Daniel Shiffman
# http://natureofcode.com

# XOR Multi-Layered Neural Network Example
# Neural network java code is all in the "src" folder
load_library :nn

require_relative './landscape'
include_package 'nn'

ITERATIONS_PER_FRAME = 5

attr_reader :inputs, :nn, :count, :land, :theta, :f, :result, :known


def setup

  size(400, 400, P3D)
  @theta = 0.0
  # Create a landscape object
  @land = Landscape.new(20, 300, 300)
  @f = create_font("Courier", 12, true)

  @nn = Network.new(2, 4)
  @count = 0
  # Create a list of 4 training inputs
  @inputs = []
  inputs << [1.0, 0]
  inputs << [0, 1.0]
  inputs << [1.0, 1.0]
  inputs << [0, 0.0]
end

def draw
  lights
  ITERATIONS_PER_FRAME.times do |i|
    inp = inputs.sample
    # Compute XOR    
    @known = ((inp[0] > 0.0 && inp[1] > 0.0) || (inp[0] < 1.0 && inp[1] < 1.0))? 0 : 1.0

    # Train that sucker!
    @result = nn.train(inp, known)
    @count += 1
  end

  # Ok, visualize the solution space
  background(175)
  push_matrix
  translate(width / 2, height / 2 + 20, -160)
  rotate_x(Math::PI / 3)
  rotate_z(theta)

  # Put a little BOX on screen
  push_matrix

  stroke(50)
  no_fill
  translate(-10, -10, 0)
  box(280)
  land.calculate(nn)
  land.render
  # Draw the landscape
  pop_matrix

  @theta += 0.0025
  pop_matrix

  # Display overal neural net stats
  network_status
end

def network_status
  mse = 0.0
  text_font(f)
  fill(0)
  text("Your friendly neighborhood neural network solving XOR.", 10, 20)
  text("Total iterations: #{count}", 10, 40)
  mse += (result - known) * (result - known)
  rmse = Math::sqrt(mse / 4.0)
  out = "Root mean squared error: #{format("%.5f", rmse)}"
  hint DISABLE_DEPTH_SORT
  text(out, 10, 60)
  hint ENABLE_DEPTH_SORT
end

# The Nature of Code
# Daniel Shiffman
# http://natureofcode.com

# "Landscape" example

class Landscape
  include Processing::Proxy

  attr_reader :scl, :w, :h, :rows, :cols, :z, :zoff



  def initialize(scl, w, h)
    @scl, @w, @h  = scl, w, h
    @cols = w / scl
    @rows = h / scl
    @z = Array.new(cols, Array.new(rows, 0.0))
  end


  # Calculate height values (based off a neural network)
  def calculate(nn)
    val = ->(curr, nn, x, y){curr * 0.95 + 0.05 *  (nn.feed_forward([x, y]) * 280.0 - 140.0)}
    @z = (0 ... cols).map{|i|
      (0 ... rows).map{|j|
        val.call(z[i][j], nn, i * 1.0/ cols, j * 1.0/cols)
      }
    }
  end

  # Render landscape as grid of quads
  def render
    # Every cell is an individual quad
    # (could use quad_strip here, but produces funny results, investigate this)
    (0 ... z.size - 1).each do |x|
      (0 ... z[0].size - 1).each do |y|

        # one quad at a time
        # each quad's color is determined by the height value at each vertex
        # (clean this part up)
        no_stroke
        push_matrix
        begin_shape(QUADS)
          translate(x * scl - w * 0.5, y * scl - h * 0.5, 0)
          fill(z[x][y]+127, 220)
          vertex(0, 0, z[x][y])
          fill(z[x+1][y]+127, 220)
          vertex(scl, 0, z[x+1][y])
          fill(z[x+1][y+1]+127, 220)
          vertex(scl, scl, z[x+1][y+1])
          fill(z[x][y+1]+127, 220)
          vertex(0, scl, z[x][y+1])
          end_shape
          pop_matrix
        end
      end
    end
  end

Followers

About Me

My photo
I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2