kristal 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/crystal/crystal.rb +63 -0
 - data/crystal/lib/atom/atom.rb +34 -0
 - data/crystal/lib/atom/lib/atom.rb +39 -0
 - data/crystal/lib/atom/lib/elements.rb +27 -0
 - data/crystal/lib/atom/test/test.rb +22 -0
 - data/crystal/lib/collection/collection.rb +48 -0
 - data/crystal/lib/collection/lib/atom.rb +21 -0
 - data/crystal/lib/collection/lib/enum.rb +33 -0
 - data/crystal/lib/collection/lib/rotate.rb +9 -0
 - data/crystal/lib/collection/lib/selector.rb +18 -0
 - data/crystal/lib/collection/lib/sort.rb +33 -0
 - data/crystal/lib/collection/test/selector.rb +27 -0
 - data/crystal/lib/collection/test/test.rb +24 -0
 - data/crystal/lib/crystal/catom.rb +41 -0
 - data/crystal/lib/crystal/surface.rb +35 -0
 - data/crystal/lib/helper/all.rb +1 -0
 - data/crystal/lib/helper/lib/array.rb +55 -0
 - data/crystal/lib/helper/lib/file.rb +152 -0
 - data/crystal/lib/helper/lib/fixnum.rb +8 -0
 - data/crystal/lib/helper/lib/hash.rb +27 -0
 - data/crystal/lib/helper/lib/kernel.rb +20 -0
 - data/crystal/lib/helper/lib/matrix.rb +12 -0
 - data/crystal/lib/helper/lib/numeric.rb +14 -0
 - data/crystal/lib/helper/lib/object.rb +35 -0
 - data/crystal/lib/helper/lib/string.rb +32 -0
 - data/crystal/lib/helper/lib/vector.rb +54 -0
 - data/crystal/lib/surface/surface.rb +30 -0
 - data/crystal/lib/surface/test/test.rb +19 -0
 - metadata +73 -0
 
    
        data/crystal/crystal.rb
    ADDED
    
    | 
         @@ -0,0 +1,63 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative 'lib/helper/all'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative 'lib/collection/collection'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'lib/surface/surface'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative 'lib/crystal/catom'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative 'lib/crystal/surface'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            class Crystal
         
     | 
| 
      
 9 
     | 
    
         
            +
              #TODO define select/reject etc for crystal module.
         
     | 
| 
      
 10 
     | 
    
         
            +
              attr_reader :a, :b, :c, :alpha, :beta, :gamma,:atoms
         
     | 
| 
      
 11 
     | 
    
         
            +
              def initialize *args
         
     | 
| 
      
 12 
     | 
    
         
            +
                @a = @b = @c = args[0].to_f
         
     | 
| 
      
 13 
     | 
    
         
            +
                @alpha = @beta = @gamma = 90.0
         
     | 
| 
      
 14 
     | 
    
         
            +
                if args.length > 2
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @b = args[1]
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @c = args[2]
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
                case args.length
         
     | 
| 
      
 19 
     | 
    
         
            +
                when 4
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @beta = args[3]
         
     | 
| 
      
 21 
     | 
    
         
            +
                when 6
         
     | 
| 
      
 22 
     | 
    
         
            +
                  @alpha = args[3]
         
     | 
| 
      
 23 
     | 
    
         
            +
                  @beta = args[4]
         
     | 
| 
      
 24 
     | 
    
         
            +
                  @gamma = args[5]
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
                @abc2xyz = conversion_matrix 
         
     | 
| 
      
 27 
     | 
    
         
            +
                @xyz2abc = @abc2xyz.inv
         
     | 
| 
      
 28 
     | 
    
         
            +
                @atoms = Collection.new
         
     | 
| 
      
 29 
     | 
    
         
            +
                @crystal = []
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
              def << arg 
         
     | 
| 
      
 32 
     | 
    
         
            +
                case arg 
         
     | 
| 
      
 33 
     | 
    
         
            +
                when Atom
         
     | 
| 
      
 34 
     | 
    
         
            +
                  arg.crystal = self
         
     | 
| 
      
 35 
     | 
    
         
            +
                  @atoms << arg
         
     | 
| 
      
 36 
     | 
    
         
            +
                  @crystal << CAtom.new(arg)
         
     | 
| 
      
 37 
     | 
    
         
            +
                when CAtom
         
     | 
| 
      
 38 
     | 
    
         
            +
                  arg.crystal = self
         
     | 
| 
      
 39 
     | 
    
         
            +
                  @atoms << arg.atom
         
     | 
| 
      
 40 
     | 
    
         
            +
                  @crystal << arg
         
     | 
| 
      
 41 
     | 
    
         
            +
                when Collection
         
     | 
| 
      
 42 
     | 
    
         
            +
                  arg.crystal = self
         
     | 
| 
      
 43 
     | 
    
         
            +
                  @atoms = arg
         
     | 
| 
      
 44 
     | 
    
         
            +
                  @crystal = [].tap{|t| @atoms.each{|a| t << CAtom.new(a)}}
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
                return self
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
              def frac(v) @xyz2abc * v.to_v end
         
     | 
| 
      
 49 
     | 
    
         
            +
              def real(v) @abc2xyz * v.to_v end
         
     | 
| 
      
 50 
     | 
    
         
            +
              def [] i, j = nil
         
     | 
| 
      
 51 
     | 
    
         
            +
                j.nil?? @crystal[i] : @crystal[i,j]
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
              def []= i, v
         
     | 
| 
      
 54 
     | 
    
         
            +
                @crystal[i] = CAtom.new(arg) if v.is_a? Atom
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
              def to_s
         
     | 
| 
      
 57 
     | 
    
         
            +
                String.new.tap{|s| @crystal.each{|e| s << e.to_s << "\n"}}
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
              private
         
     | 
| 
      
 60 
     | 
    
         
            +
              def method_missing *args, &block
         
     | 
| 
      
 61 
     | 
    
         
            +
                @atoms.send(*args, &block)
         
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative "lib/atom"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative "lib/elements"
         
     | 
| 
      
 3 
     | 
    
         
            +
            class Atom
         
     | 
| 
      
 4 
     | 
    
         
            +
              attr_reader :pos, :crystal, :type, :fixed
         
     | 
| 
      
 5 
     | 
    
         
            +
              def initialize params = {}
         
     | 
| 
      
 6 
     | 
    
         
            +
                @type = Elements[params[:type]] || Elements[:X]
         
     | 
| 
      
 7 
     | 
    
         
            +
                @name = (params[:name]||@type.name).to_sym
         
     | 
| 
      
 8 
     | 
    
         
            +
                @pos = (params[:pos].to_v rescue nil)
         
     | 
| 
      
 9 
     | 
    
         
            +
                @crystal = params[:crystal]
         
     | 
| 
      
 10 
     | 
    
         
            +
                @fixed = params[:fixed]
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
              def type= (el)
         
     | 
| 
      
 13 
     | 
    
         
            +
                @type = Elements[el.to_sym]
         
     | 
| 
      
 14 
     | 
    
         
            +
                @name = @type.name
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
              def name() @name.to_s end
         
     | 
| 
      
 17 
     | 
    
         
            +
              def name=(s)
         
     | 
| 
      
 18 
     | 
    
         
            +
                @name = s.to_sym
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
              def pos=(v)
         
     | 
| 
      
 21 
     | 
    
         
            +
                @pos = v.to_v
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
              def fixed=(*a)
         
     | 
| 
      
 24 
     | 
    
         
            +
                a.flatten!
         
     | 
| 
      
 25 
     | 
    
         
            +
                @fixed = a.length == 3 ? a : a * 3
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
              def crystal=(c)
         
     | 
| 
      
 28 
     | 
    
         
            +
                @crystal = c if (c.is_a? Crystal rescue false)
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
              def evaluate str, b=nil
         
     | 
| 
      
 31 
     | 
    
         
            +
                str = str.gsub(/={1,2}/,"==").gsub(/(\[[^\]]*\])/,'\1.to_v')
         
     | 
| 
      
 32 
     | 
    
         
            +
                eval(str) ? true : false
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Atom
         
     | 
| 
      
 2 
     | 
    
         
            +
              def x() @pos[0] end
         
     | 
| 
      
 3 
     | 
    
         
            +
              def y() @pos[1] end
         
     | 
| 
      
 4 
     | 
    
         
            +
              def z() @pos[2] end
         
     | 
| 
      
 5 
     | 
    
         
            +
              def x=(p) 
         
     | 
| 
      
 6 
     | 
    
         
            +
                @pos = Vector[p,y,z] 
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
              def y=(p) 
         
     | 
| 
      
 9 
     | 
    
         
            +
                @pos = Vector[x,p,z] 
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
              def z=(p) 
         
     | 
| 
      
 12 
     | 
    
         
            +
                @pos = Vector[x,y,p] 
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
              def has_crystal?() !(@crystal.nil?) end
         
     | 
| 
      
 15 
     | 
    
         
            +
              def move! v, n = 1
         
     | 
| 
      
 16 
     | 
    
         
            +
                @pos += v.to_v * n
         
     | 
| 
      
 17 
     | 
    
         
            +
                self
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
              def move v, n = 1
         
     | 
| 
      
 20 
     | 
    
         
            +
                ret = self.dup
         
     | 
| 
      
 21 
     | 
    
         
            +
                ret.move! v,n
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
              def dist other
         
     | 
| 
      
 24 
     | 
    
         
            +
                pos = other.is_a?(Atom) ? other.pos : other.to_v
         
     | 
| 
      
 25 
     | 
    
         
            +
                has_crystal? ? crystal.dist(self, other):(@pos - pos).magnitude
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
              def dup
         
     | 
| 
      
 28 
     | 
    
         
            +
                Atom.new(to_hash)
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
              def to_hash
         
     | 
| 
      
 31 
     | 
    
         
            +
                { :type => @type.name.to_sym, :name => @name, :pos => @pos, :fixed => @fixed, :crystal => @crystal }
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
              def to_s f = '%8.4f'
         
     | 
| 
      
 34 
     | 
    
         
            +
                ("%-6s" + "#{f} " * 3) % ([name] + pos.to_a) + (fixed.nil? ? "" : fixed.map{|v| v ? 0 : 1}.join(" "))
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
              def inspect
         
     | 
| 
      
 37 
     | 
    
         
            +
                to_hash.to_s
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Atom
         
     | 
| 
      
 2 
     | 
    
         
            +
              Elements = {
         
     | 
| 
      
 3 
     | 
    
         
            +
                :O => {
         
     | 
| 
      
 4 
     | 
    
         
            +
                  :z => 8,
         
     | 
| 
      
 5 
     | 
    
         
            +
                  :m => 15.999,
         
     | 
| 
      
 6 
     | 
    
         
            +
                  :fname => "Oxygen",
         
     | 
| 
      
 7 
     | 
    
         
            +
                  :name => :O,
         
     | 
| 
      
 8 
     | 
    
         
            +
                  :pp => []
         
     | 
| 
      
 9 
     | 
    
         
            +
                },
         
     | 
| 
      
 10 
     | 
    
         
            +
                :Ti => {
         
     | 
| 
      
 11 
     | 
    
         
            +
                  :z => 22,
         
     | 
| 
      
 12 
     | 
    
         
            +
                  :m => 47.867,
         
     | 
| 
      
 13 
     | 
    
         
            +
                  :fname => "Titanium",
         
     | 
| 
      
 14 
     | 
    
         
            +
                  :name => :Ti,
         
     | 
| 
      
 15 
     | 
    
         
            +
                  :pp => []
         
     | 
| 
      
 16 
     | 
    
         
            +
                },
         
     | 
| 
      
 17 
     | 
    
         
            +
                :X => {
         
     | 
| 
      
 18 
     | 
    
         
            +
                  :z => 1,
         
     | 
| 
      
 19 
     | 
    
         
            +
                  :m => 1,
         
     | 
| 
      
 20 
     | 
    
         
            +
                  :fname => "Unspecified",
         
     | 
| 
      
 21 
     | 
    
         
            +
                  :name => :X,
         
     | 
| 
      
 22 
     | 
    
         
            +
                  :pp => []
         
     | 
| 
      
 23 
     | 
    
         
            +
                }
         
     | 
| 
      
 24 
     | 
    
         
            +
              }
         
     | 
| 
      
 25 
     | 
    
         
            +
              Elements.method_access = true
         
     | 
| 
      
 26 
     | 
    
         
            +
              Elements.each{ |_,v| v.method_access = true }
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'minitest/autorun'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'minitest/pride'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative "../atom.rb"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            describe "Atom" do
         
     | 
| 
      
 6 
     | 
    
         
            +
              before do
         
     | 
| 
      
 7 
     | 
    
         
            +
                @atom = Atom.new :element => :Os, :pos => [0,0,0]
         
     | 
| 
      
 8 
     | 
    
         
            +
                @atom2 = Atom.new :pos => [0,3,4]
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
              it "can be copied around" do
         
     | 
| 
      
 11 
     | 
    
         
            +
                @atom2 = @atom.move([2,3,4])
         
     | 
| 
      
 12 
     | 
    
         
            +
                @atom2.pos.must_equal(Vector[2,3,4])
         
     | 
| 
      
 13 
     | 
    
         
            +
                @atom.pos.must_equal(Vector[0,0,0])
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
              it "and can be moved" do
         
     | 
| 
      
 16 
     | 
    
         
            +
                @atom.move!(Vector[1,0,0],2).pos.must_equal(Vector[2,0,0])
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
              it "can calculate distances" do
         
     | 
| 
      
 19 
     | 
    
         
            +
                @atom.dist(@atom2).must_equal(5)
         
     | 
| 
      
 20 
     | 
    
         
            +
                @atom2.dist([2,3,4]).must_equal(2)
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,48 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative "../atom/atom"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative "lib/enum"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative "lib/selector"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative "lib/sort"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative "lib/atom"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative "lib/rotate"
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            class Collection
         
     | 
| 
      
 9 
     | 
    
         
            +
              attr_reader :crystal
         
     | 
| 
      
 10 
     | 
    
         
            +
              def initialize *args
         
     | 
| 
      
 11 
     | 
    
         
            +
                @collection = []
         
     | 
| 
      
 12 
     | 
    
         
            +
                @tol = 0
         
     | 
| 
      
 13 
     | 
    
         
            +
                [*args].each{ |arg| self << arg }
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
              def << arg
         
     | 
| 
      
 16 
     | 
    
         
            +
                if arg.is_a? Atom
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @collection << arg unless @collection.include? arg
         
     | 
| 
      
 18 
     | 
    
         
            +
                  return self
         
     | 
| 
      
 19 
     | 
    
         
            +
                elsif arg.is_a? Collection
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @collection += arg.to_a
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @collection.uniq!
         
     | 
| 
      
 22 
     | 
    
         
            +
                  return self
         
     | 
| 
      
 23 
     | 
    
         
            +
                elsif arg.is_a? Array
         
     | 
| 
      
 24 
     | 
    
         
            +
                  @collection += arg if arg.all?{|v| v.is_a? Atom}
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @collection.uniq!
         
     | 
| 
      
 26 
     | 
    
         
            +
                  return self
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
                return false
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
              def length() @collection.length end
         
     | 
| 
      
 31 
     | 
    
         
            +
              def pop n = 1
         
     | 
| 
      
 32 
     | 
    
         
            +
                @collection.pop n
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
              def [] i, j = nil
         
     | 
| 
      
 35 
     | 
    
         
            +
                j.nil?? @collection[i] : Collection.new.tap{|t| t << @collection[i,j]}
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
              def []= index, atom
         
     | 
| 
      
 38 
     | 
    
         
            +
                if atom.is_a?(Atom) 
         
     | 
| 
      
 39 
     | 
    
         
            +
                  @collection[index]=atom 
         
     | 
| 
      
 40 
     | 
    
         
            +
                  @collection = @collection.uniq.compact
         
     | 
| 
      
 41 
     | 
    
         
            +
                  true
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
                  false
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
              def to_s
         
     | 
| 
      
 46 
     | 
    
         
            +
                String.new.tap{|s| @collection.each{|e| s << e.to_s << "\n"}}
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Collection
         
     | 
| 
      
 2 
     | 
    
         
            +
              def move! v, n=1
         
     | 
| 
      
 3 
     | 
    
         
            +
                @collection.each{|atom| atom.move! v, n}
         
     | 
| 
      
 4 
     | 
    
         
            +
                return self
         
     | 
| 
      
 5 
     | 
    
         
            +
              end
         
     | 
| 
      
 6 
     | 
    
         
            +
              def move v, n=1
         
     | 
| 
      
 7 
     | 
    
         
            +
                dup.move! v, n
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
              def fixed= bool = true
         
     | 
| 
      
 10 
     | 
    
         
            +
                @collection.each{|atom| atom.fixed = bool}
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
              def type= str
         
     | 
| 
      
 13 
     | 
    
         
            +
                @collection.each{|atom| atom.type = str}
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
              def name= str
         
     | 
| 
      
 16 
     | 
    
         
            +
                @collection.each{|atom| atom.name = str}
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
              def crystal= crystal
         
     | 
| 
      
 19 
     | 
    
         
            +
                @collection.each{|atom| atom.crystal = crystal}
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Collection
         
     | 
| 
      
 2 
     | 
    
         
            +
              # include Enumerable
         
     | 
| 
      
 3 
     | 
    
         
            +
              def each
         
     | 
| 
      
 4 
     | 
    
         
            +
                if block_given?
         
     | 
| 
      
 5 
     | 
    
         
            +
                  @collection.each { |e| yield(e) }
         
     | 
| 
      
 6 
     | 
    
         
            +
                else
         
     | 
| 
      
 7 
     | 
    
         
            +
                  Enumerator.new(self, :each)
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
              end 
         
     | 
| 
      
 10 
     | 
    
         
            +
              def map!
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @collection.map!{|c| yield(c); c}
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
              def map &block
         
     | 
| 
      
 14 
     | 
    
         
            +
                dup.map!(&block)
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
              def clone
         
     | 
| 
      
 17 
     | 
    
         
            +
                Collection.new.tap{|t| t << @collection }
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
              def dup
         
     | 
| 
      
 20 
     | 
    
         
            +
                Collection.new.tap do |t|
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @collection.each do |e|
         
     | 
| 
      
 22 
     | 
    
         
            +
                    t << e.dup
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
              def to_a 
         
     | 
| 
      
 27 
     | 
    
         
            +
                @collection
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
              def remove arg 
         
     | 
| 
      
 30 
     | 
    
         
            +
                arg.is_a?(Atom)? @collection.delete(arg): @collection.delete_at(arg)
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
              alias :delete :remove
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Collection
         
     | 
| 
      
 2 
     | 
    
         
            +
              def select! str = nil, &block
         
     | 
| 
      
 3 
     | 
    
         
            +
                @collection.select!{|v| v.evaluate(str)} unless str.nil?
         
     | 
| 
      
 4 
     | 
    
         
            +
                @collection.select!(&block) if block_given?
         
     | 
| 
      
 5 
     | 
    
         
            +
                self
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
              def reject! str = nil, &block
         
     | 
| 
      
 8 
     | 
    
         
            +
                @collection.reject!{|v| v.evaluate(str)} unless str.nil?
         
     | 
| 
      
 9 
     | 
    
         
            +
                @collection.reject!(&block) if block_given?
         
     | 
| 
      
 10 
     | 
    
         
            +
                self
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
              def select str = nil, &block
         
     | 
| 
      
 13 
     | 
    
         
            +
                dup.select! str, &block
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
              def reject str = nil, &block
         
     | 
| 
      
 16 
     | 
    
         
            +
                dup.select! str, &block
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Collection
         
     | 
| 
      
 2 
     | 
    
         
            +
              def sort! *keys
         
     | 
| 
      
 3 
     | 
    
         
            +
                tol = []
         
     | 
| 
      
 4 
     | 
    
         
            +
                tol << keys.pop while keys[-1].is_a? Numeric
         
     | 
| 
      
 5 
     | 
    
         
            +
                @collection.sort! do |a,b|
         
     | 
| 
      
 6 
     | 
    
         
            +
                  result = 0
         
     | 
| 
      
 7 
     | 
    
         
            +
                  ks = keys.dup
         
     | 
| 
      
 8 
     | 
    
         
            +
                  t = tol.dup
         
     | 
| 
      
 9 
     | 
    
         
            +
                  while result == 0 and ks.length > 0
         
     | 
| 
      
 10 
     | 
    
         
            +
                    key = ks.shift
         
     | 
| 
      
 11 
     | 
    
         
            +
                    t.push @tol if t.length == 0
         
     | 
| 
      
 12 
     | 
    
         
            +
                    case key
         
     | 
| 
      
 13 
     | 
    
         
            +
                    when :type
         
     | 
| 
      
 14 
     | 
    
         
            +
                      result = (a.type.name <=> b.type.name)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    when Symbol
         
     | 
| 
      
 16 
     | 
    
         
            +
                      result = a.send(key)
         
     | 
| 
      
 17 
     | 
    
         
            +
                      if result.is_a? Numeric
         
     | 
| 
      
 18 
     | 
    
         
            +
                        result = result.approx_sort(b.send(key), t.pop)
         
     | 
| 
      
 19 
     | 
    
         
            +
                      else
         
     | 
| 
      
 20 
     | 
    
         
            +
                        result = result <=> b.send(key)
         
     | 
| 
      
 21 
     | 
    
         
            +
                      end
         
     | 
| 
      
 22 
     | 
    
         
            +
                    else
         
     | 
| 
      
 23 
     | 
    
         
            +
                      result = (key.to_a * a.pos).approx_sort(key.to_a * b.pos, t.pop)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                  result
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
                return @collection
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
              def sort *keys
         
     | 
| 
      
 31 
     | 
    
         
            +
                dup.sort! *keys
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'minitest/autorun'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'minitest/pride'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative "../../helper/lib/array"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            describe "Selector" do
         
     | 
| 
      
 6 
     | 
    
         
            +
              before "parser and yielder" do
         
     | 
| 
      
 7 
     | 
    
         
            +
                def parse arg
         
     | 
| 
      
 8 
     | 
    
         
            +
                  conj = arg.scan(/and|or/).map{|v| v == 'and' ? :& : :|}
         
     | 
| 
      
 9 
     | 
    
         
            +
                  args = arg.split /and|or/
         
     | 
| 
      
 10 
     | 
    
         
            +
                  procs = []
         
     | 
| 
      
 11 
     | 
    
         
            +
                  args.each do |arg|
         
     | 
| 
      
 12 
     | 
    
         
            +
                    operator = arg.scan(/[>=<]{1,2}/)[0]
         
     | 
| 
      
 13 
     | 
    
         
            +
                    arg = arg.split(operator).map{|v| v.numeric?? Float(v) : v} #.to_sym}
         
     | 
| 
      
 14 
     | 
    
         
            +
                    procs.push Proc.new{|x| x.send(operator, arg[1])}
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  var = a
         
     | 
| 
      
 17 
     | 
    
         
            +
                  return Pr
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
                def calc *args
         
     | 
| 
      
 20 
     | 
    
         
            +
                  yield *args
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
              it "parses (and/or)s" do
         
     | 
| 
      
 24 
     | 
    
         
            +
                c = "x < 10 and y > 10 or z > 1"
         
     | 
| 
      
 25 
     | 
    
         
            +
                assert calc(11,1,2, &parse(c))
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'minitest/autorun'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'minitest/pride'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative "../Collection.rb"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            describe "Simple Cubic" do
         
     | 
| 
      
 6 
     | 
    
         
            +
              before do
         
     | 
| 
      
 7 
     | 
    
         
            +
                a = Atom.new :element => :Ti, :pos => [0,0,0]
         
     | 
| 
      
 8 
     | 
    
         
            +
                @coll = Collection.new
         
     | 
| 
      
 9 
     | 
    
         
            +
                @coll << a << a.move([0,0,1])
         
     | 
| 
      
 10 
     | 
    
         
            +
                @coll << @coll.move([0,1,0])
         
     | 
| 
      
 11 
     | 
    
         
            +
                @coll << @coll.move([1,1,0])
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
              it "can be cloned and deep-cloned" do
         
     | 
| 
      
 14 
     | 
    
         
            +
                clone = @coll.clone
         
     | 
| 
      
 15 
     | 
    
         
            +
                deep_clone = @coll.dup
         
     | 
| 
      
 16 
     | 
    
         
            +
                assert clone.object_id != @coll.object_id
         
     | 
| 
      
 17 
     | 
    
         
            +
                assert clone[0].object_id == @coll[0].object_id
         
     | 
| 
      
 18 
     | 
    
         
            +
                assert deep_clone.object_id != @coll.object_id
         
     | 
| 
      
 19 
     | 
    
         
            +
                assert deep_clone[0].object_id != @coll[0].object_id
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
              it "can be sorted in arbitrary directions" do
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,41 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class CAtom
         
     | 
| 
      
 2 
     | 
    
         
            +
              attr_reader :atom
         
     | 
| 
      
 3 
     | 
    
         
            +
              def initialize arg
         
     | 
| 
      
 4 
     | 
    
         
            +
                if arg.is_a? Atom
         
     | 
| 
      
 5 
     | 
    
         
            +
                  @atom = arg
         
     | 
| 
      
 6 
     | 
    
         
            +
                else
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @atom = Atom.new(arg)
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
              def pos= arg 
         
     | 
| 
      
 11 
     | 
    
         
            +
                @atom.pos = @atom.crystal.real(arg)
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
              def pos 
         
     | 
| 
      
 14 
     | 
    
         
            +
                @atom.crystal.frac(@atom.pos)
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
              def x() pos[0] end
         
     | 
| 
      
 17 
     | 
    
         
            +
              def y() pos[0] end
         
     | 
| 
      
 18 
     | 
    
         
            +
              def z() pos[0] end
         
     | 
| 
      
 19 
     | 
    
         
            +
              def x=(p) 
         
     | 
| 
      
 20 
     | 
    
         
            +
                @atom.pos = @atom.crystal.real([p,y,z])
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
              def y=(p) 
         
     | 
| 
      
 23 
     | 
    
         
            +
                @atom.pos = @atom.crystal.real([x,p,z])
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
              def z=(p) 
         
     | 
| 
      
 26 
     | 
    
         
            +
                @atom.pos = @atom.crystal.real([x,y,p])
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
              def move!(v, n = 1)
         
     | 
| 
      
 29 
     | 
    
         
            +
                @atom.move! @atom.crystal.real(v), n
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
              def move(v, n) 
         
     | 
| 
      
 32 
     | 
    
         
            +
                @atom.move @atom.crystal.real(v), n
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
              def to_s f = '%8.4f'
         
     | 
| 
      
 35 
     | 
    
         
            +
                ("%-6s" + "#{f} " * 3) % ([@atom.name] + pos.to_a) + (fixed.nil? ? "" : fixed.map{|v| v ? 0 : 1}.join(" "))
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
              private
         
     | 
| 
      
 38 
     | 
    
         
            +
              def method_missing *args
         
     | 
| 
      
 39 
     | 
    
         
            +
                @atom.send(*args)
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Crystal
         
     | 
| 
      
 2 
     | 
    
         
            +
              def surface v, p, tol = 0
         
     | 
| 
      
 3 
     | 
    
         
            +
                Surface.new(surface_converter(v), real(p), tol)
         
     | 
| 
      
 4 
     | 
    
         
            +
              end
         
     | 
| 
      
 5 
     | 
    
         
            +
              private
         
     | 
| 
      
 6 
     | 
    
         
            +
              def conversion_matrix
         
     | 
| 
      
 7 
     | 
    
         
            +
                cos = -> x {Math.cos( x * Math::PI / 180 ).round(10)}
         
     | 
| 
      
 8 
     | 
    
         
            +
                sin = -> x {Math.sin( x * Math::PI / 180 ).round(10)}
         
     | 
| 
      
 9 
     | 
    
         
            +
                Matrix[
         
     | 
| 
      
 10 
     | 
    
         
            +
                  [@a, @b * cos[@gamma], @c * cos[@beta]],
         
     | 
| 
      
 11 
     | 
    
         
            +
                  [0, @b * sin[@gamma], @c * (cos[@alpha] - cos[@beta] * cos[@gamma]) / sin[@gamma]],
         
     | 
| 
      
 12 
     | 
    
         
            +
                  [0, 0, @c * (1 - cos[@alpha] ** 2 - cos[@beta] ** 2 - cos[@gamma] ** 2 + 2 * cos[@gamma] * cos[@alpha] * cos[@beta])]
         
     | 
| 
      
 13 
     | 
    
         
            +
                ]
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
              def surface_converter arr
         
     | 
| 
      
 16 
     | 
    
         
            +
                x = arr[0] == 0 ? Vector[1.0 / 0, 0, 0] : real([1.0 / arr[0], 0, 0])
         
     | 
| 
      
 17 
     | 
    
         
            +
                y = arr[1] == 0 ? Vector[0,1.0/0,0] : real([0, 1.0 / arr[1], 0])
         
     | 
| 
      
 18 
     | 
    
         
            +
                z = arr[2] == 0 ? Vector[0,0,1.0/0] : real([0, 0, 1.0 / arr[2]])
         
     | 
| 
      
 19 
     | 
    
         
            +
                hxy = get_h x, y
         
     | 
| 
      
 20 
     | 
    
         
            +
                get_h hxy, z
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
              def get_h v1, v2
         
     | 
| 
      
 23 
     | 
    
         
            +
                m = [v1.magnitude, v2.magnitude, (v1-v2).magnitude]
         
     | 
| 
      
 24 
     | 
    
         
            +
                if m[0] == 1.0/0
         
     | 
| 
      
 25 
     | 
    
         
            +
                  v2
         
     | 
| 
      
 26 
     | 
    
         
            +
                elsif m[1] == 1.0/0
         
     | 
| 
      
 27 
     | 
    
         
            +
                  v1
         
     | 
| 
      
 28 
     | 
    
         
            +
                else
         
     | 
| 
      
 29 
     | 
    
         
            +
                  s = m.reduce(:+)/2
         
     | 
| 
      
 30 
     | 
    
         
            +
                  h = 2 * (s * m.map{|v| s - v}.reduce(:*)).sqrt / m[2]
         
     | 
| 
      
 31 
     | 
    
         
            +
                  angle = (Math.acos(h/m[0]) * 180 / Math::PI).round(10)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  (v1/m[0]).rotate(v1.cross(v2), angle)*h
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Dir[File.dirname(__FILE__) + "/lib/*.rb"].each {|file| require_relative file }
         
     | 
| 
         @@ -0,0 +1,55 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative 'string'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative 'object'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'numeric'
         
     | 
| 
      
 4 
     | 
    
         
            +
            class Array
         
     | 
| 
      
 5 
     | 
    
         
            +
              #exclusive elements
         
     | 
| 
      
 6 
     | 
    
         
            +
              def ^(other)
         
     | 
| 
      
 7 
     | 
    
         
            +
                (self - other) | (other - self)
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
              #new array from two arrays. 
         
     | 
| 
      
 10 
     | 
    
         
            +
              def combine(other, op=nil)
         
     | 
| 
      
 11 
     | 
    
         
            +
                return [] if self.empty? || other.empty?
         
     | 
| 
      
 12 
     | 
    
         
            +
                clipped = self[0..other.length-1]
         
     | 
| 
      
 13 
     | 
    
         
            +
                zipped = clipped.zip(other)
         
     | 
| 
      
 14 
     | 
    
         
            +
                if op
         
     | 
| 
      
 15 
     | 
    
         
            +
                  zipped.map { |a, b| a.send(op, b) }
         
     | 
| 
      
 16 
     | 
    
         
            +
                else
         
     | 
| 
      
 17 
     | 
    
         
            +
                  zipped.map { |a, b| yield(a, b) }
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
              alias :old_x :*
         
     | 
| 
      
 21 
     | 
    
         
            +
              def *(x)
         
     | 
| 
      
 22 
     | 
    
         
            +
                if (x.is_a? Vector rescue false)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  (Matrix[self] * x)[0]
         
     | 
| 
      
 24 
     | 
    
         
            +
                else
         
     | 
| 
      
 25 
     | 
    
         
            +
                  old_x x
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
              def to_v
         
     | 
| 
      
 29 
     | 
    
         
            +
                Vector[*self]
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
              #TODO Rewrite/Rename these:
         
     | 
| 
      
 32 
     | 
    
         
            +
              def numbers!
         
     | 
| 
      
 33 
     | 
    
         
            +
                i = length - 1
         
     | 
| 
      
 34 
     | 
    
         
            +
                self.reverse_each do |elem|
         
     | 
| 
      
 35 
     | 
    
         
            +
                  if elem.is_a? Array
         
     | 
| 
      
 36 
     | 
    
         
            +
                    self[i] = elem.numbers!
         
     | 
| 
      
 37 
     | 
    
         
            +
                  else
         
     | 
| 
      
 38 
     | 
    
         
            +
                    elem.numeric? ? self[i] = Float(elem):self.delete_at(i)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                  i -= 1
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
                return self
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
              def numerify!
         
     | 
| 
      
 45 
     | 
    
         
            +
                self.each_index do |i|
         
     | 
| 
      
 46 
     | 
    
         
            +
                  if self[i].is_a? Array
         
     | 
| 
      
 47 
     | 
    
         
            +
                    self[i] = self[i].numerify!
         
     | 
| 
      
 48 
     | 
    
         
            +
                  else
         
     | 
| 
      
 49 
     | 
    
         
            +
                    self[i] = Float(self[i]) if self[i].numeric?
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
                return self
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,152 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class File
         
     | 
| 
      
 2 
     | 
    
         
            +
              # repeat last ff/rew command
         
     | 
| 
      
 3 
     | 
    
         
            +
              def repeat
         
     | 
| 
      
 4 
     | 
    
         
            +
                if @find_registry[:method] == :ff
         
     | 
| 
      
 5 
     | 
    
         
            +
                  seek(1,1)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  ff(@find_registry[:re])
         
     | 
| 
      
 7 
     | 
    
         
            +
                else
         
     | 
| 
      
 8 
     | 
    
         
            +
                  rew(@find_registry[:re])
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
              # find all occurences of args (with or) 
         
     | 
| 
      
 12 
     | 
    
         
            +
              # in the file egardless of the current
         
     | 
| 
      
 13 
     | 
    
         
            +
              # position
         
     | 
| 
      
 14 
     | 
    
         
            +
              def findall *args
         
     | 
| 
      
 15 
     | 
    
         
            +
                p = pos
         
     | 
| 
      
 16 
     | 
    
         
            +
                seek(0)
         
     | 
| 
      
 17 
     | 
    
         
            +
                results = [ ff(*args).pos ]
         
     | 
| 
      
 18 
     | 
    
         
            +
                while !repeat.nil?
         
     | 
| 
      
 19 
     | 
    
         
            +
                  results.push pos
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
                seek(p)
         
     | 
| 
      
 22 
     | 
    
         
            +
                return results
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
              # do not rewind, just give
         
     | 
| 
      
 25 
     | 
    
         
            +
              # the position that rew would 
         
     | 
| 
      
 26 
     | 
    
         
            +
              # rewind to.
         
     | 
| 
      
 27 
     | 
    
         
            +
              def rew? *args
         
     | 
| 
      
 28 
     | 
    
         
            +
                p = pos 
         
     | 
| 
      
 29 
     | 
    
         
            +
                p1 = rew(*args)
         
     | 
| 
      
 30 
     | 
    
         
            +
                p1.nil? ? p1 = nil : p1 = pos
         
     | 
| 
      
 31 
     | 
    
         
            +
                seek p
         
     | 
| 
      
 32 
     | 
    
         
            +
                return p1
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
              # do not fast forward, just give
         
     | 
| 
      
 35 
     | 
    
         
            +
              # the position that ff would fast
         
     | 
| 
      
 36 
     | 
    
         
            +
              # forward to.
         
     | 
| 
      
 37 
     | 
    
         
            +
              def ff? *args
         
     | 
| 
      
 38 
     | 
    
         
            +
                p = pos 
         
     | 
| 
      
 39 
     | 
    
         
            +
                p1 = ff(*args)
         
     | 
| 
      
 40 
     | 
    
         
            +
                p1.nil? ? p1 = nil : p1 = pos
         
     | 
| 
      
 41 
     | 
    
         
            +
                seek p
         
     | 
| 
      
 42 
     | 
    
         
            +
                return p1
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
              # rewind until it finds one of args
         
     | 
| 
      
 45 
     | 
    
         
            +
              # supplied as string or regex 
         
     | 
| 
      
 46 
     | 
    
         
            +
              # returns nil if nothing found 
         
     | 
| 
      
 47 
     | 
    
         
            +
              def rew *args
         
     | 
| 
      
 48 
     | 
    
         
            +
                p = pos
         
     | 
| 
      
 49 
     | 
    
         
            +
                psearch = p
         
     | 
| 
      
 50 
     | 
    
         
            +
                re = Regexp.union(args)
         
     | 
| 
      
 51 
     | 
    
         
            +
                @find_registry = { :method => :rew, :re => re }
         
     | 
| 
      
 52 
     | 
    
         
            +
                begin
         
     | 
| 
      
 53 
     | 
    
         
            +
                  break if psearch == 0
         
     | 
| 
      
 54 
     | 
    
         
            +
                  512 > pos ? buffer = pos : buffer = 512 # buffer = [512, p].min
         
     | 
| 
      
 55 
     | 
    
         
            +
                  seek(-buffer, 1)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  psearch = pos
         
     | 
| 
      
 57 
     | 
    
         
            +
                  chunk = read(buffer+80)
         
     | 
| 
      
 58 
     | 
    
         
            +
                  seek(-chunk.length, 1)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  check = chunk.rindex(re)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  if !check.nil? and buffer <= check
         
     | 
| 
      
 61 
     | 
    
         
            +
                    chunk.slice!(-(chunk.length-buffer)..-1)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    check = chunk.rindex(re)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
                end while check.nil? or buffer <= check 
         
     | 
| 
      
 65 
     | 
    
         
            +
                begin
         
     | 
| 
      
 66 
     | 
    
         
            +
                  if buffer <= check
         
     | 
| 
      
 67 
     | 
    
         
            +
                    seek p
         
     | 
| 
      
 68 
     | 
    
         
            +
                    return nil
         
     | 
| 
      
 69 
     | 
    
         
            +
                  else 
         
     | 
| 
      
 70 
     | 
    
         
            +
                    seek(psearch + check)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    return self
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
                rescue
         
     | 
| 
      
 74 
     | 
    
         
            +
                  seek p
         
     | 
| 
      
 75 
     | 
    
         
            +
                  return nil
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
              # fast forward until it finds one of args
         
     | 
| 
      
 79 
     | 
    
         
            +
              # supplied as string or regex 
         
     | 
| 
      
 80 
     | 
    
         
            +
              # returns nil if nothing found 
         
     | 
| 
      
 81 
     | 
    
         
            +
              def ff *args
         
     | 
| 
      
 82 
     | 
    
         
            +
                p = pos
         
     | 
| 
      
 83 
     | 
    
         
            +
                re = Regexp.union(args)
         
     | 
| 
      
 84 
     | 
    
         
            +
                @find_registry = { :method => :ff, :re => re }
         
     | 
| 
      
 85 
     | 
    
         
            +
                buffer = 512
         
     | 
| 
      
 86 
     | 
    
         
            +
                begin
         
     | 
| 
      
 87 
     | 
    
         
            +
                  psearch = pos
         
     | 
| 
      
 88 
     | 
    
         
            +
                  chunk = read(buffer)
         
     | 
| 
      
 89 
     | 
    
         
            +
                  seek(-80,1) unless eof?
         
     | 
| 
      
 90 
     | 
    
         
            +
                  check = chunk.index(re)
         
     | 
| 
      
 91 
     | 
    
         
            +
                end while check.nil? and !eof?
         
     | 
| 
      
 92 
     | 
    
         
            +
                begin
         
     | 
| 
      
 93 
     | 
    
         
            +
                  seek(psearch + check)
         
     | 
| 
      
 94 
     | 
    
         
            +
                  return self
         
     | 
| 
      
 95 
     | 
    
         
            +
                rescue
         
     | 
| 
      
 96 
     | 
    
         
            +
                  seek p
         
     | 
| 
      
 97 
     | 
    
         
            +
                  return nil
         
     | 
| 
      
 98 
     | 
    
         
            +
                end
         
     | 
| 
      
 99 
     | 
    
         
            +
              end
         
     | 
| 
      
 100 
     | 
    
         
            +
              # unix head like utility, returns lines
         
     | 
| 
      
 101 
     | 
    
         
            +
              # as an array. optional arguments cur for
         
     | 
| 
      
 102 
     | 
    
         
            +
              # start from current line (default is start)
         
     | 
| 
      
 103 
     | 
    
         
            +
              # from beggining; reset for do not change
         
     | 
| 
      
 104 
     | 
    
         
            +
              # current position (default).
         
     | 
| 
      
 105 
     | 
    
         
            +
              def head(n, cur=false, reset=true)
         
     | 
| 
      
 106 
     | 
    
         
            +
                #eof guard
         
     | 
| 
      
 107 
     | 
    
         
            +
                p = pos
         
     | 
| 
      
 108 
     | 
    
         
            +
                line_start
         
     | 
| 
      
 109 
     | 
    
         
            +
                lines = []
         
     | 
| 
      
 110 
     | 
    
         
            +
                seek(0) unless cur
         
     | 
| 
      
 111 
     | 
    
         
            +
                for i in 1..n 
         
     | 
| 
      
 112 
     | 
    
         
            +
                  break if eof?
         
     | 
| 
      
 113 
     | 
    
         
            +
                  lines.push(readline.chomp)
         
     | 
| 
      
 114 
     | 
    
         
            +
                end
         
     | 
| 
      
 115 
     | 
    
         
            +
                seek(p) if reset
         
     | 
| 
      
 116 
     | 
    
         
            +
                return lines
         
     | 
| 
      
 117 
     | 
    
         
            +
              end
         
     | 
| 
      
 118 
     | 
    
         
            +
              # unix tail like utility, returns lines
         
     | 
| 
      
 119 
     | 
    
         
            +
              # as an array. optional arguments cur for
         
     | 
| 
      
 120 
     | 
    
         
            +
              # start from current line (default is start)
         
     | 
| 
      
 121 
     | 
    
         
            +
              # from end; reset for do not change
         
     | 
| 
      
 122 
     | 
    
         
            +
              # current position (default).
         
     | 
| 
      
 123 
     | 
    
         
            +
              def tail(n, cur=false, reset=true)
         
     | 
| 
      
 124 
     | 
    
         
            +
                p = pos
         
     | 
| 
      
 125 
     | 
    
         
            +
                chunks = ''
         
     | 
| 
      
 126 
     | 
    
         
            +
                lines = 0
         
     | 
| 
      
 127 
     | 
    
         
            +
                cur ? line_end : seek(size)
         
     | 
| 
      
 128 
     | 
    
         
            +
                begin
         
     | 
| 
      
 129 
     | 
    
         
            +
                  p1 = pos
         
     | 
| 
      
 130 
     | 
    
         
            +
                  p1 < 512 ? buffer = p1 : buffer = 512
         
     | 
| 
      
 131 
     | 
    
         
            +
                  seek(-buffer, 1)
         
     | 
| 
      
 132 
     | 
    
         
            +
                  chunk = read(buffer)
         
     | 
| 
      
 133 
     | 
    
         
            +
                  lines += chunk.count("\n")
         
     | 
| 
      
 134 
     | 
    
         
            +
                  chunks = chunk + chunks
         
     | 
| 
      
 135 
     | 
    
         
            +
                  seek(-chunk.size,1)
         
     | 
| 
      
 136 
     | 
    
         
            +
                end while lines < ( n + 1 ) && p1 != 0
         
     | 
| 
      
 137 
     | 
    
         
            +
                ary = chunks.split(/\n/)
         
     | 
| 
      
 138 
     | 
    
         
            +
                reset ? seek(p) : seek(p1-1-(ary.last(n).join("\n").length))
         
     | 
| 
      
 139 
     | 
    
         
            +
                return ary.last(n)
         
     | 
| 
      
 140 
     | 
    
         
            +
              end
         
     | 
| 
      
 141 
     | 
    
         
            +
              # move to the first char of current line
         
     | 
| 
      
 142 
     | 
    
         
            +
              def line_start
         
     | 
| 
      
 143 
     | 
    
         
            +
                unless readchar == "\n"
         
     | 
| 
      
 144 
     | 
    
         
            +
                  return rew(/^/)
         
     | 
| 
      
 145 
     | 
    
         
            +
                end
         
     | 
| 
      
 146 
     | 
    
         
            +
                return self
         
     | 
| 
      
 147 
     | 
    
         
            +
              end
         
     | 
| 
      
 148 
     | 
    
         
            +
              # move to the last char of current line
         
     | 
| 
      
 149 
     | 
    
         
            +
              def line_end
         
     | 
| 
      
 150 
     | 
    
         
            +
                return ff(/$/)
         
     | 
| 
      
 151 
     | 
    
         
            +
              end
         
     | 
| 
      
 152 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Hash
         
     | 
| 
      
 2 
     | 
    
         
            +
              def extract(*ks)
         
     | 
| 
      
 3 
     | 
    
         
            +
                existing = keys & ks
         
     | 
| 
      
 4 
     | 
    
         
            +
                Hash[existing.zip(values_at(*existing))]
         
     | 
| 
      
 5 
     | 
    
         
            +
              end
         
     | 
| 
      
 6 
     | 
    
         
            +
              def has_shape?(shape)
         
     | 
| 
      
 7 
     | 
    
         
            +
                all? do |k, v|
         
     | 
| 
      
 8 
     | 
    
         
            +
                  Hash === v ? v.has_shape?(shape[k]) : shape[k] === v
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
              attr_accessor :method_access
         
     | 
| 
      
 12 
     | 
    
         
            +
              alias :old_m :method_missing
         
     | 
| 
      
 13 
     | 
    
         
            +
              def method_missing(m)
         
     | 
| 
      
 14 
     | 
    
         
            +
                if (@method_access.nil? ? (@@method_access rescue false) : @method_access)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  if has_key? m
         
     | 
| 
      
 16 
     | 
    
         
            +
                    return self[m]
         
     | 
| 
      
 17 
     | 
    
         
            +
                  elsif has_key? m.to_s
         
     | 
| 
      
 18 
     | 
    
         
            +
                    return self[m.to_s]
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
                return old_m(m)
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 24 
     | 
    
         
            +
                def method_access=(bool) @@method_access = bool end
         
     | 
| 
      
 25 
     | 
    
         
            +
                def method_access() @@method_access end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Kernel
         
     | 
| 
      
 2 
     | 
    
         
            +
              def fn(*funs)
         
     | 
| 
      
 3 
     | 
    
         
            +
                -> x do
         
     | 
| 
      
 4 
     | 
    
         
            +
                  funs.inject(x) do |v,f|
         
     | 
| 
      
 5 
     | 
    
         
            +
                    Proc === f ? f.call(v) : v.send(f)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  end
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
              def prompt(text='', conversion=nil)
         
     | 
| 
      
 10 
     | 
    
         
            +
                print text unless text.empty?
         
     | 
| 
      
 11 
     | 
    
         
            +
                input = gets.chomp
         
     | 
| 
      
 12 
     | 
    
         
            +
                CONVERSIONS.include?(conversion) ? input.send(conversion) : input
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
              def with(object,&block)
         
     | 
| 
      
 15 
     | 
    
         
            +
                object.instance_eval(&block)
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
              # def with(o, &blk)
         
     | 
| 
      
 18 
     | 
    
         
            +
              #   o.tap(&blk)
         
     | 
| 
      
 19 
     | 
    
         
            +
              # end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,12 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'matrix'
         
     | 
| 
      
 2 
     | 
    
         
            +
            class Matrix
         
     | 
| 
      
 3 
     | 
    
         
            +
              def to_s format='%.4f'
         
     | 
| 
      
 4 
     | 
    
         
            +
                return "" if empty?
         
     | 
| 
      
 5 
     | 
    
         
            +
                f = column_vectors.map(&->x{"%#{x.longest_string(format)}s"}).join(" ")
         
     | 
| 
      
 6 
     | 
    
         
            +
                map{|v| format % v}.row_vectors.map{|v| f % v.to_a}.join("\n")
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
              def inspect format = '%.4f'
         
     | 
| 
      
 9 
     | 
    
         
            +
                return "Matrix[]" if empty?
         
     | 
| 
      
 10 
     | 
    
         
            +
                (["\nMatrix[ "] + ["        "]*(row_size-1)).zip(to_s.lines).map{|v| v.join}.join() + " ]"
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Numeric
         
     | 
| 
      
 2 
     | 
    
         
            +
              (Math.methods - Module.methods - ["hypot", "ldexp"]).each do |method|
         
     | 
| 
      
 3 
     | 
    
         
            +
                define_method method do
         
     | 
| 
      
 4 
     | 
    
         
            +
                  Math.send method, self
         
     | 
| 
      
 5 
     | 
    
         
            +
                end
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
              def approx_sort other, tol = self.to_f/1000
         
     | 
| 
      
 8 
     | 
    
         
            +
                d = self - other
         
     | 
| 
      
 9 
     | 
    
         
            +
                d > tol ? 1 : (-d > tol ? -1 : 0)
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
              def numeric?
         
     | 
| 
      
 12 
     | 
    
         
            +
                true
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Object
         
     | 
| 
      
 2 
     | 
    
         
            +
              alias :old_display :display
         
     | 
| 
      
 3 
     | 
    
         
            +
              def display(new_line = true)
         
     | 
| 
      
 4 
     | 
    
         
            +
                m = new_line ? :puts : :print
         
     | 
| 
      
 5 
     | 
    
         
            +
                self.tap { |o| send(m, o) }
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
              def it
         
     | 
| 
      
 8 
     | 
    
         
            +
                self
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
              def numeric?
         
     | 
| 
      
 11 
     | 
    
         
            +
                false
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
              def deep_clone
         
     | 
| 
      
 14 
     | 
    
         
            +
                return @deep_cloning_obj if @deep_cloning
         
     | 
| 
      
 15 
     | 
    
         
            +
                @deep_cloning_obj = clone
         
     | 
| 
      
 16 
     | 
    
         
            +
                @deep_cloning_obj.instance_variables.each do |var|
         
     | 
| 
      
 17 
     | 
    
         
            +
                  val = @deep_cloning_obj.instance_variable_get(var)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @deep_cloning = true
         
     | 
| 
      
 20 
     | 
    
         
            +
                    val = val.deep_clone
         
     | 
| 
      
 21 
     | 
    
         
            +
                  rescue TypeError
         
     | 
| 
      
 22 
     | 
    
         
            +
                    next
         
     | 
| 
      
 23 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 24 
     | 
    
         
            +
                    @deep_cloning = false
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                  @deep_cloning_obj.instance_variable_set(var, val)
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
                deep_cloning_obj = @deep_cloning_obj
         
     | 
| 
      
 29 
     | 
    
         
            +
                @deep_cloning_obj = nil
         
     | 
| 
      
 30 
     | 
    
         
            +
                deep_cloning_obj
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
              def to_sym
         
     | 
| 
      
 33 
     | 
    
         
            +
                self.to_s.to_sym
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,32 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class String
         
     | 
| 
      
 2 
     | 
    
         
            +
              def paste str, j = ' ', align = :left
         
     | 
| 
      
 3 
     | 
    
         
            +
                if str.is_a? Array
         
     | 
| 
      
 4 
     | 
    
         
            +
                  tmp = self.dup
         
     | 
| 
      
 5 
     | 
    
         
            +
                  str.each do |s|
         
     | 
| 
      
 6 
     | 
    
         
            +
                    tmp = tmp.paste s, j, align
         
     | 
| 
      
 7 
     | 
    
         
            +
                  end
         
     | 
| 
      
 8 
     | 
    
         
            +
                  tmp
         
     | 
| 
      
 9 
     | 
    
         
            +
                else
         
     | 
| 
      
 10 
     | 
    
         
            +
                  slines = self.lines.map(&:chomp)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  s1lines = str.lines.map(&:chomp)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  (s1lines.count - slines.count).times{slines.push ""}
         
     | 
| 
      
 13 
     | 
    
         
            +
                  l = slines.map(&:length).max
         
     | 
| 
      
 14 
     | 
    
         
            +
                  l1 = s1lines.map(&:length).max
         
     | 
| 
      
 15 
     | 
    
         
            +
                  case align
         
     | 
| 
      
 16 
     | 
    
         
            +
                  when :left
         
     | 
| 
      
 17 
     | 
    
         
            +
                    f  = "%-#{l}s"
         
     | 
| 
      
 18 
     | 
    
         
            +
                    f1 = "%-#{l1}s"
         
     | 
| 
      
 19 
     | 
    
         
            +
                  when :right
         
     | 
| 
      
 20 
     | 
    
         
            +
                    f  = "%#{l}s"
         
     | 
| 
      
 21 
     | 
    
         
            +
                    f1 = "%#{l1}s"
         
     | 
| 
      
 22 
     | 
    
         
            +
                  else
         
     | 
| 
      
 23 
     | 
    
         
            +
                    f  = '%s'
         
     | 
| 
      
 24 
     | 
    
         
            +
                    f1 = '%s'
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                  slines.map{|v| f % v}.zip(s1lines.map{|v| f1 % v}).map{|v| v.join(j)}.join("\n")
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
              def numeric?
         
     | 
| 
      
 30 
     | 
    
         
            +
                Float(self) != nil rescue false
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,54 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Vector
         
     | 
| 
      
 2 
     | 
    
         
            +
              def to_s format = '%.4f'
         
     | 
| 
      
 3 
     | 
    
         
            +
                return "" if size == 0
         
     | 
| 
      
 4 
     | 
    
         
            +
                w = longest_string format
         
     | 
| 
      
 5 
     | 
    
         
            +
                map{|v| "%#{w}s" % (format % v)}.to_a.join("\n")
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
              def inspect format = '%.4f'
         
     | 
| 
      
 8 
     | 
    
         
            +
                return "Vector[]" if size == 0
         
     | 
| 
      
 9 
     | 
    
         
            +
                (["\nVector[ "] + ["        "]*(size-1)).zip(to_s.lines).map{|v| v.join}.join() +" ]"
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
              def longest_string format
         
     | 
| 
      
 12 
     | 
    
         
            +
                map{|x| (format % x).length}.max
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
              def to_v
         
     | 
| 
      
 15 
     | 
    
         
            +
                self
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
              def rotate direction, origin = Vector[0,0,0], angle
         
     | 
| 
      
 18 
     | 
    
         
            +
                Vector[*(rotation_matrix(direction, origin, angle) * Vector[*(self),1]).to_a[0,3]]
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
              def cross v2
         
     | 
| 
      
 21 
     | 
    
         
            +
                raise ArgumentError, "Vectors should be 3D" if self.size != 3 or v2.size != 3
         
     | 
| 
      
 22 
     | 
    
         
            +
                Vector[
         
     | 
| 
      
 23 
     | 
    
         
            +
                  self[1]*v2[2] - self[2]*v2[1],
         
     | 
| 
      
 24 
     | 
    
         
            +
                  self[2]*v2[0] - self[0]*v2[2],
         
     | 
| 
      
 25 
     | 
    
         
            +
                  self[0]*v2[1] - self[1]*v2[0]
         
     | 
| 
      
 26 
     | 
    
         
            +
                ]
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
              private
         
     | 
| 
      
 29 
     | 
    
         
            +
              def rotation_matrix direction, origin, theta 
         
     | 
| 
      
 30 
     | 
    
         
            +
                u,v,w = direction.normalize.to_a
         
     | 
| 
      
 31 
     | 
    
         
            +
                a,b,c = origin.to_a
         
     | 
| 
      
 32 
     | 
    
         
            +
                cos = Math.cos(theta / 180.0 * Math::PI).round(10)
         
     | 
| 
      
 33 
     | 
    
         
            +
                sin = Math.sin(theta / 180.0 * Math::PI).round(10)
         
     | 
| 
      
 34 
     | 
    
         
            +
                return Matrix.columns([
         
     | 
| 
      
 35 
     | 
    
         
            +
                  [ u**2+cos*(v**2+w**2),
         
     | 
| 
      
 36 
     | 
    
         
            +
                    u*v*(1-cos)+w*sin,
         
     | 
| 
      
 37 
     | 
    
         
            +
                    u*w*(1-cos)-v*sin,
         
     | 
| 
      
 38 
     | 
    
         
            +
                    0 ],
         
     | 
| 
      
 39 
     | 
    
         
            +
                    [ v*u*(1-cos)-w*sin,
         
     | 
| 
      
 40 
     | 
    
         
            +
                      v**2+cos*(u**2+w**2),
         
     | 
| 
      
 41 
     | 
    
         
            +
                      v*w*(1-cos)+u*sin,
         
     | 
| 
      
 42 
     | 
    
         
            +
                      0],
         
     | 
| 
      
 43 
     | 
    
         
            +
                      [ u*w*(1-cos)+v*sin,
         
     | 
| 
      
 44 
     | 
    
         
            +
                        w*v*(1-cos)-u*sin,
         
     | 
| 
      
 45 
     | 
    
         
            +
                        w**2+cos*(v**2+u**2),
         
     | 
| 
      
 46 
     | 
    
         
            +
                        0 ],
         
     | 
| 
      
 47 
     | 
    
         
            +
                        [ (a*(v**2+w**2)-u*(b*v+c*w))*(1-cos)+(b*w-c*v)*sin,
         
     | 
| 
      
 48 
     | 
    
         
            +
                          (b*(u**2+w**2)-v*(a*u+c*w))*(1-cos)+(c*u-a*w)*sin,
         
     | 
| 
      
 49 
     | 
    
         
            +
                          (c*(u**2+v**2)-w*(a*u+b*v))*(1-cos)+(a*v-b*u)*sin,
         
     | 
| 
      
 50 
     | 
    
         
            +
                          1 ]
         
     | 
| 
      
 51 
     | 
    
         
            +
                ])
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Surface
         
     | 
| 
      
 2 
     | 
    
         
            +
              attr_accessor :tol
         
     | 
| 
      
 3 
     | 
    
         
            +
              attr_reader :normal, :p
         
     | 
| 
      
 4 
     | 
    
         
            +
              def initialize v, p, tol = 0
         
     | 
| 
      
 5 
     | 
    
         
            +
                @normal = v.to_v || nil
         
     | 
| 
      
 6 
     | 
    
         
            +
                @p = p.to_v || Vector[0,0,0]
         
     | 
| 
      
 7 
     | 
    
         
            +
                @tol = tol
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
              def normal=(a) @normal=a.to_v end
         
     | 
| 
      
 10 
     | 
    
         
            +
              def p=(a) @p=a.to_v end
         
     | 
| 
      
 11 
     | 
    
         
            +
              def above? p, tol = @tol
         
     | 
| 
      
 12 
     | 
    
         
            +
                dist(p) + tol < 0
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
              def below? p, tol = @tol
         
     | 
| 
      
 15 
     | 
    
         
            +
                dist(p) - tol > 0
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
              def include? p, tol = @tol
         
     | 
| 
      
 18 
     | 
    
         
            +
                dist(p).abs <= tol
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
              def dist p
         
     | 
| 
      
 21 
     | 
    
         
            +
                p = p.pos if p.is_a? Atom
         
     | 
| 
      
 22 
     | 
    
         
            +
                (p.to_v- @p).to_a * @normal / @normal.magnitude
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
              def rotate! d,o,a
         
     | 
| 
      
 25 
     | 
    
         
            +
                @normal = @normal.rotate!(d.to_v,o.to_v,a)
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
              def move! v
         
     | 
| 
      
 28 
     | 
    
         
            +
                @p += v.to_v
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'minitest/autorun'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'minitest/pride'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative "../surface.rb"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            describe "Surface" do
         
     | 
| 
      
 6 
     | 
    
         
            +
              before do
         
     | 
| 
      
 7 
     | 
    
         
            +
                @surface = Surface.new [0,0,1], [1,1,1], 0.5
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
              it "know up and down" do
         
     | 
| 
      
 10 
     | 
    
         
            +
                assert @surface.below? [-1,-3,5]
         
     | 
| 
      
 11 
     | 
    
         
            +
                assert @surface.above? [5,13,0]
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
              it "tolerates deviations" do
         
     | 
| 
      
 14 
     | 
    
         
            +
                assert @surface.include? [2,5,0.5]
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
              it "gives the distances" do
         
     | 
| 
      
 17 
     | 
    
         
            +
                @surface.dist([0,0,0]).must_equal -1
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,73 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: kristal
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.0.1
         
     | 
| 
      
 5 
     | 
    
         
            +
              prerelease: 
         
     | 
| 
      
 6 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 7 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 8 
     | 
    
         
            +
            - Sencer Selcuk
         
     | 
| 
      
 9 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 10 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 11 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2013-02-10 00:00:00.000000000 Z
         
     | 
| 
      
 13 
     | 
    
         
            +
            dependencies: []
         
     | 
| 
      
 14 
     | 
    
         
            +
            description: A crystal structure manipulator wanna-be
         
     | 
| 
      
 15 
     | 
    
         
            +
            email: sencerselcuk@twitter
         
     | 
| 
      
 16 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 17 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 18 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 19 
     | 
    
         
            +
            files:
         
     | 
| 
      
 20 
     | 
    
         
            +
            - crystal/crystal.rb
         
     | 
| 
      
 21 
     | 
    
         
            +
            - crystal/lib/atom/atom.rb
         
     | 
| 
      
 22 
     | 
    
         
            +
            - crystal/lib/atom/lib/atom.rb
         
     | 
| 
      
 23 
     | 
    
         
            +
            - crystal/lib/atom/lib/elements.rb
         
     | 
| 
      
 24 
     | 
    
         
            +
            - crystal/lib/atom/test/test.rb
         
     | 
| 
      
 25 
     | 
    
         
            +
            - crystal/lib/collection/collection.rb
         
     | 
| 
      
 26 
     | 
    
         
            +
            - crystal/lib/collection/lib/atom.rb
         
     | 
| 
      
 27 
     | 
    
         
            +
            - crystal/lib/collection/lib/enum.rb
         
     | 
| 
      
 28 
     | 
    
         
            +
            - crystal/lib/collection/lib/rotate.rb
         
     | 
| 
      
 29 
     | 
    
         
            +
            - crystal/lib/collection/lib/selector.rb
         
     | 
| 
      
 30 
     | 
    
         
            +
            - crystal/lib/collection/lib/sort.rb
         
     | 
| 
      
 31 
     | 
    
         
            +
            - crystal/lib/collection/test/selector.rb
         
     | 
| 
      
 32 
     | 
    
         
            +
            - crystal/lib/collection/test/test.rb
         
     | 
| 
      
 33 
     | 
    
         
            +
            - crystal/lib/crystal/catom.rb
         
     | 
| 
      
 34 
     | 
    
         
            +
            - crystal/lib/crystal/surface.rb
         
     | 
| 
      
 35 
     | 
    
         
            +
            - crystal/lib/helper/all.rb
         
     | 
| 
      
 36 
     | 
    
         
            +
            - crystal/lib/helper/lib/array.rb
         
     | 
| 
      
 37 
     | 
    
         
            +
            - crystal/lib/helper/lib/file.rb
         
     | 
| 
      
 38 
     | 
    
         
            +
            - crystal/lib/helper/lib/fixnum.rb
         
     | 
| 
      
 39 
     | 
    
         
            +
            - crystal/lib/helper/lib/hash.rb
         
     | 
| 
      
 40 
     | 
    
         
            +
            - crystal/lib/helper/lib/kernel.rb
         
     | 
| 
      
 41 
     | 
    
         
            +
            - crystal/lib/helper/lib/matrix.rb
         
     | 
| 
      
 42 
     | 
    
         
            +
            - crystal/lib/helper/lib/numeric.rb
         
     | 
| 
      
 43 
     | 
    
         
            +
            - crystal/lib/helper/lib/object.rb
         
     | 
| 
      
 44 
     | 
    
         
            +
            - crystal/lib/helper/lib/string.rb
         
     | 
| 
      
 45 
     | 
    
         
            +
            - crystal/lib/helper/lib/vector.rb
         
     | 
| 
      
 46 
     | 
    
         
            +
            - crystal/lib/surface/surface.rb
         
     | 
| 
      
 47 
     | 
    
         
            +
            - crystal/lib/surface/test/test.rb
         
     | 
| 
      
 48 
     | 
    
         
            +
            homepage: 
         
     | 
| 
      
 49 
     | 
    
         
            +
            licenses: []
         
     | 
| 
      
 50 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 51 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 52 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 53 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 54 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 55 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 56 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 57 
     | 
    
         
            +
              - - ! '>='
         
     | 
| 
      
 58 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 59 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 60 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 61 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 62 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 63 
     | 
    
         
            +
              - - ! '>='
         
     | 
| 
      
 64 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 65 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 66 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 67 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 68 
     | 
    
         
            +
            rubygems_version: 1.8.23
         
     | 
| 
      
 69 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 70 
     | 
    
         
            +
            specification_version: 3
         
     | 
| 
      
 71 
     | 
    
         
            +
            summary: A crystal structure manipulator wanna-be
         
     | 
| 
      
 72 
     | 
    
         
            +
            test_files: []
         
     | 
| 
      
 73 
     | 
    
         
            +
            has_rdoc: 
         
     |