<commit_before>require "rain/version"

module Rain
  module GA
    # Encoder {{{
    class Encoder
      attr_reader :encoding, :decoding, :values, :num_bits

      def initialize(values=nil, num_bits=nil)
        # by default, keep everything about the same size
        @values     = values
        @num_values = values.length
        @num_bits   = Math.log2(@num_values).ceil
        build_encoding_key
      end

      def build_encoding_key
        unless @values.nil?
          @num_bits ||= Math.log2(@values.length).ceil

          @decoding = Hash[@values.each_with_index.map { |val,i|
            [i.to_s(2).rjust(@num_bits,'0'), val]
          }]

          @encoding = Hash[@values.each_with_index.map { |val,i|
            [val, i.to_s(2).rjust(@num_bits,'0')]
          }]

          @bitstrings = @decoding.keys
        end
      end

      def randval
        rand_value
      end

      def randbs
        rand_bitstring
      end

      def rand_value
        @values[rand(0..@num_values-1)]
      end

      def rand_bitstring
        @bitstrings[rand(0..@num_values-1)]
      end

      def encode(value)
        #puts "encoding #{value} as #{@encoding[value]}"
        @encoding[value]
      end

      def decode(value)
        #puts "decoding #{value} as #{@decoding[value]}"
        @decoding[value]
      end

      def length
        #puts "length is #{@num_bits}"
        @num_bits
      end
    end
    # }}}

    # Gene {{{
    class Gene
      attr_reader :encoder

      def initialize(encoder=nil, val=nil, encoded=true)
        raise "Gene requires encoder to be present" if encoder.nil?

        @encoder = encoder

        # if no value is provided then
        # initialize a random value
        if val.nil?
          @bitstring = @encoder.randbs
        else
          if encoded
            @bitstring = val
          else
            @bitstring = @encoder.encode(val)
          end
        end
      end

      def value=(val)
        @bitstring = @encoder.encode(val)
      end

      # set the value for this gene
      def bitstring=(bitstring)
        @bitstring = val
      end

      def valid?
        # if it has a value, and the value is
        # known by the encoder
        !encoded.nil? && !decoded.nil?
      end

      # the value of this gene is stored
      # in decoded form already
      def decoded
        @encoder.decode(encoded)
      end

      # helper function that passes
      # through to encoder object
      # to decode the value
      def encoded
        @bitstring.rjust(length, "0")
      end

      def randomize!
        @bitstring = @encoder.randbs
      end

      def length
        @encoder.length
      end
    end
    # }}}

    # Genome {{{
    class Genome
      attr_accessor :encoders, :genes, :use_reals

      def initialize(genes=[])
        @use_reals = false
        @genes = genes
      end

      def genes_use_real_numbers?
        @use_reals
      end

      def value=(vals)
        new_genes = []

        # split the new bitstring up by gene
        @genes.each_with_index do |g,x|
          # create a new gene using the old
          # encoder but using the new value
          n = Gene.new(g.encoder)
          n.value = vals[x]

          new_genes << n
        end

        @genes = new_genes
      end

      def bitstring=(bitstring)
        new_genes = []

        # split the new bitstring up by gene
        @genes.each do |g|
          # split off one gene worth of bits
          encoded_gene, bitstring = split_array(bitstring, g.length)

          # create a new gene using the old encoder
          # but using the new bitstring
          new_genes << Gene.new(g.encoder, encoded_gene)
        end

        @genes = new_genes
      end

      def valid?
        # none of the genes are invalid, 
        # i.e. all of the genes are valid
        !@genes.map(&:valid?).uniq.include?(false)
      end

      def encoded
        puts "total length: #{@genes.map(&:length).reduce(:+)}"
        puts "num genes: #{@genes.length}"
        @genes.map(&:encoded).join.rjust(@genes.map(&:length).reduce(:+), "0")
      end

      def decoded
        @genes.map(&:decoded).join
      end

      def randomize!
        @genes.each do |g|
          g.randomize!
        end
      end

      def split(split_point)
        split_array(encoded, split_point)
      end

      def encoders
        @genes.map(&:encoder)<commit_msg>Remove debugger calls<commit_after>require "rain/version"

module Rain
  module GA
    # Encoder {{{
    class Encoder
      attr_reader :encoding, :decoding, :values, :num_bits

      def initialize(values=nil, num_bits=nil)
        # by default, keep everything about the same size
        @values     = values
        @num_values = values.length
        @num_bits   = Math.log2(@num_values).ceil
        build_encoding_key
      end

      def build_encoding_key
        unless @values.nil?
          @num_bits ||= Math.log2(@values.length).ceil

          @decoding = Hash[@values.each_with_index.map { |val,i|
            [i.to_s(2).rjust(@num_bits,'0'), val]
          }]

          @encoding = Hash[@values.each_with_index.map { |val,i|
            [val, i.to_s(2).rjust(@num_bits,'0')]
          }]

          @bitstrings = @decoding.keys
        end
      end

      def randval
        rand_value
      end

      def randbs
        rand_bitstring
      end

      def rand_value
        @values[rand(0..@num_values-1)]
      end

      def rand_bitstring
        @bitstrings[rand(0..@num_values-1)]
      end

      def encode(value)
        #puts "encoding #{value} as #{@encoding[value]}"
        @encoding[value]
      end

      def decode(value)
        #puts "decoding #{value} as #{@decoding[value]}"
        @decoding[value]
      end

      def length
        #puts "length is #{@num_bits}"
        @num_bits
      end
    end
    # }}}

    # Gene {{{
    class Gene
      attr_reader :encoder

      def initialize(encoder=nil, val=nil, encoded=true)
        raise "Gene requires encoder to be present" if encoder.nil?

        @encoder = encoder

        # if no value is provided then
        # initialize a random value
        if val.nil?
          @bitstring = @encoder.randbs
        else
          if encoded
            @bitstring = val
          else
            @bitstring = @encoder.encode(val)
          end
        end
      end

      def value=(val)
        @bitstring = @encoder.encode(val)
      end

      # set the value for this gene
      def bitstring=(bitstring)
        @bitstring = val
      end

      def valid?
        # if it has a value, and the value is
        # known by the encoder
        !encoded.nil? && !decoded.nil?
      end

      # the value of this gene is stored
      # in decoded form already
      def decoded
        @encoder.decode(encoded)
      end

      # helper function that passes
      # through to encoder object
      # to decode the value
      def encoded
        @bitstring.rjust(length, "0")
      end

      def randomize!
        @bitstring = @encoder.randbs
      end

      def length
        @encoder.length
      end
    end
    # }}}

    # Genome {{{
    class Genome
      attr_accessor :encoders, :genes, :use_reals

      def initialize(genes=[])
        @use_reals = false
        @genes = genes
      end

      def genes_use_real_numbers?
        @use_reals
      end

      def value=(vals)
        new_genes = []

        # split the new bitstring up by gene
        @genes.each_with_index do |g,x|
          # create a new gene using the old
          # encoder but using the new value
          n = Gene.new(g.encoder)
          n.value = vals[x]

          new_genes << n
        end

        @genes = new_genes
      end

      def bitstring=(bitstring)
        new_genes = []

        # split the new bitstring up by gene
        @genes.each do |g|
          # split off one gene worth of bits
          encoded_gene, bitstring = split_array(bitstring, g.length)

          # create a new gene using the old encoder
          # but using the new bitstring
          new_genes << Gene.new(g.encoder, encoded_gene)
        end

        @genes = new_genes
      end

      def valid?
        # none of the genes are invalid, 
        # i.e. all of the genes are valid
        !@genes.map(&:valid?).uniq.include?(false)
      end

      def encoded
        @genes.map(&:encoded).join.rjust(@genes.map(&:length).reduce(:+), "0")
      end

      def decoded
        @genes.map(&:decoded).join
      end

      def randomize!
        @genes.each do |g|
          g.randomize!
        end
      end

      def split(split_point)
        split_array(encoded, split_point)
      end

      def encoders
        @genes.map(&:encoder)
{'fraction_non_alphanumeric': 0.09398195729130981, 'fraction_numerical': 0.0027406646111682084, 'mean_word_length': 1.653939393939394, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4278657', 'n_tokens_mistral': 2738, 'n_tokens_neox': 2578, 'n_words': 723}