mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* benchmark/driver.rb: fix notations.
* benchmark/bm_loop_whileloop.rb: ditto. * benchmark/bm_loop_whileloop2.rb: ditto. * benchmark/bm_app_uri.rb: added. * benchmark/bm_vm1_ivar_set.rb: ditto. * benchmark/bm_so_binary_trees.rb: added from Computer Language Benchmarks Game (http://shootout.alioth.debian.org/). * benchmark/bm_so_fannkuch.rb: ditto. * benchmark/bm_so_mandelbrot.rb: ditto. * benchmark/bm_so_meteor_contest.rb: ditto. * benchmark/bm_so_nbody.rb: ditto. * benchmark/bm_so_nsieve.rb: ditto. * benchmark/bm_so_nsieve_bits.rb: ditto. * benchmark/bm_so_partial_sums.rb: ditto. * benchmark/bm_so_pidigits.rb: ditto. * benchmark/bm_so_spectralnorm.rb: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13548 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
335fe1ee7b
commit
30b2cb380e
16 changed files with 1173 additions and 4 deletions
33
ChangeLog
33
ChangeLog
|
@ -1,3 +1,36 @@
|
|||
Fri Sep 28 19:14:51 2007 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* benchmark/driver.rb: fix notations.
|
||||
|
||||
* benchmark/bm_loop_whileloop.rb: ditto.
|
||||
|
||||
* benchmark/bm_loop_whileloop2.rb: ditto.
|
||||
|
||||
* benchmark/bm_app_uri.rb: added.
|
||||
|
||||
* benchmark/bm_vm1_ivar_set.rb: ditto.
|
||||
|
||||
* benchmark/bm_so_binary_trees.rb: added from Computer Language
|
||||
Benchmarks Game (http://shootout.alioth.debian.org/).
|
||||
|
||||
* benchmark/bm_so_fannkuch.rb: ditto.
|
||||
|
||||
* benchmark/bm_so_mandelbrot.rb: ditto.
|
||||
|
||||
* benchmark/bm_so_meteor_contest.rb: ditto.
|
||||
|
||||
* benchmark/bm_so_nbody.rb: ditto.
|
||||
|
||||
* benchmark/bm_so_nsieve.rb: ditto.
|
||||
|
||||
* benchmark/bm_so_nsieve_bits.rb: ditto.
|
||||
|
||||
* benchmark/bm_so_partial_sums.rb: ditto.
|
||||
|
||||
* benchmark/bm_so_pidigits.rb: ditto.
|
||||
|
||||
* benchmark/bm_so_spectralnorm.rb: ditto.
|
||||
|
||||
Fri Sep 28 16:22:52 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* vm_core.h (rb_vm_struct): fix typo: bufferd -> buffered.
|
||||
|
|
8
benchmark/bm_app_uri.rb
Normal file
8
benchmark/bm_app_uri.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
require 'uri'
|
||||
|
||||
100_000.times{
|
||||
uri = URI.parse('http://www.ruby-lang.org')
|
||||
uri.scheme
|
||||
uri.host
|
||||
uri.port
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
i = 0
|
||||
while i<30000000 # benchmark loop 1
|
||||
i=0
|
||||
while i<30_000_000 # benchmark loop 1
|
||||
i+=1
|
||||
end
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
i=0
|
||||
while i<6000000 # benchmark loop 2
|
||||
while i< 6_000_000 # benchmark loop 2
|
||||
i+=1
|
||||
end
|
||||
|
||||
|
|
57
benchmark/bm_so_binary_trees.rb
Normal file
57
benchmark/bm_so_binary_trees.rb
Normal file
|
@ -0,0 +1,57 @@
|
|||
# The Computer Language Shootout Benchmarks
|
||||
# http://shootout.alioth.debian.org
|
||||
#
|
||||
# contributed by Jesse Millikan
|
||||
|
||||
# disable output
|
||||
def STDOUT.write_ *args
|
||||
end
|
||||
|
||||
def item_check(tree)
|
||||
if tree[0] == nil
|
||||
tree[1]
|
||||
else
|
||||
tree[1] + item_check(tree[0]) - item_check(tree[2])
|
||||
end
|
||||
end
|
||||
|
||||
def bottom_up_tree(item, depth)
|
||||
if depth > 0
|
||||
item_item = 2 * item
|
||||
depth -= 1
|
||||
[bottom_up_tree(item_item - 1, depth), item, bottom_up_tree(item_item, depth)]
|
||||
else
|
||||
[nil, item, nil]
|
||||
end
|
||||
end
|
||||
|
||||
max_depth = 12 # 16 # ARGV[0].to_i
|
||||
min_depth = 4
|
||||
|
||||
max_depth = min_depth + 2 if min_depth + 2 > max_depth
|
||||
|
||||
stretch_depth = max_depth + 1
|
||||
stretch_tree = bottom_up_tree(0, stretch_depth)
|
||||
|
||||
puts "stretch tree of depth #{stretch_depth}\t check: #{item_check(stretch_tree)}"
|
||||
stretch_tree = nil
|
||||
|
||||
long_lived_tree = bottom_up_tree(0, max_depth)
|
||||
|
||||
min_depth.step(max_depth + 1, 2) do |depth|
|
||||
iterations = 2**(max_depth - depth + min_depth)
|
||||
|
||||
check = 0
|
||||
|
||||
for i in 1..iterations
|
||||
temp_tree = bottom_up_tree(i, depth)
|
||||
check += item_check(temp_tree)
|
||||
|
||||
temp_tree = bottom_up_tree(-i, depth)
|
||||
check += item_check(temp_tree)
|
||||
end
|
||||
|
||||
puts "#{iterations * 2}\t trees of depth #{depth}\t check: #{check}"
|
||||
end
|
||||
|
||||
puts "long lived tree of depth #{max_depth}\t check: #{item_check(long_lived_tree)}"
|
45
benchmark/bm_so_fannkuch.rb
Normal file
45
benchmark/bm_so_fannkuch.rb
Normal file
|
@ -0,0 +1,45 @@
|
|||
# The Computer Language Shootout
|
||||
# http://shootout.alioth.debian.org/
|
||||
# Contributed by Sokolov Yura
|
||||
# Modified by Ryan Williams
|
||||
|
||||
def fannkuch(n)
|
||||
maxFlips, m, r, check = 0, n-1, n, 0
|
||||
count = (1..n).to_a
|
||||
perm = (1..n).to_a
|
||||
|
||||
while true
|
||||
if check < 30
|
||||
puts "#{perm}"
|
||||
check += 1
|
||||
end
|
||||
|
||||
while r != 1
|
||||
count[r-1] = r
|
||||
r -= 1
|
||||
end
|
||||
|
||||
if perm[0] != 1 and perm[m] != n
|
||||
perml = perm.clone #.dup
|
||||
flips = 0
|
||||
while (k = perml.first ) != 1
|
||||
perml = perml.slice!(0, k).reverse + perml
|
||||
flips += 1
|
||||
end
|
||||
maxFlips = flips if flips > maxFlips
|
||||
end
|
||||
while true
|
||||
if r==n then return maxFlips end
|
||||
perm.insert r,perm.shift
|
||||
break if (count[r] -= 1) > 0
|
||||
r += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def puts *args
|
||||
end
|
||||
|
||||
N = 10 # (ARGV[0] || 1).to_i
|
||||
puts "Pfannkuchen(#{N}) = #{fannkuch(N)}"
|
||||
|
57
benchmark/bm_so_mandelbrot.rb
Normal file
57
benchmark/bm_so_mandelbrot.rb
Normal file
|
@ -0,0 +1,57 @@
|
|||
# The Computer Language Benchmarks Game
|
||||
# http://shootout.alioth.debian.org/
|
||||
#
|
||||
# contributed by Karl von Laudermann
|
||||
# modified by Jeremy Echols
|
||||
|
||||
size = 600 # ARGV[0].to_i
|
||||
|
||||
puts "P4\n#{size} #{size}"
|
||||
|
||||
ITER = 49 # Iterations - 1 for easy for..in looping
|
||||
LIMIT_SQUARED = 4.0 # Presquared limit
|
||||
|
||||
byte_acc = 0
|
||||
bit_num = 0
|
||||
|
||||
count_size = size - 1 # Precomputed size for easy for..in looping
|
||||
|
||||
# For..in loops are faster than .upto, .downto, .times, etc.
|
||||
for y in 0..count_size
|
||||
for x in 0..count_size
|
||||
zr = 0.0
|
||||
zi = 0.0
|
||||
cr = (2.0*x/size)-1.5
|
||||
ci = (2.0*y/size)-1.0
|
||||
escape = false
|
||||
|
||||
# To make use of the for..in code, we use a dummy variable,
|
||||
# like one would in C
|
||||
for dummy in 0..ITER
|
||||
tr = zr*zr - zi*zi + cr
|
||||
ti = 2*zr*zi + ci
|
||||
zr, zi = tr, ti
|
||||
|
||||
if (zr*zr+zi*zi) > LIMIT_SQUARED
|
||||
escape = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
byte_acc = (byte_acc << 1) | (escape ? 0b0 : 0b1)
|
||||
bit_num += 1
|
||||
|
||||
# Code is very similar for these cases, but using separate blocks
|
||||
# ensures we skip the shifting when it's unnecessary, which is most cases.
|
||||
if (bit_num == 8)
|
||||
print byte_acc.chr
|
||||
byte_acc = 0
|
||||
bit_num = 0
|
||||
elsif (x == count_size)
|
||||
byte_acc <<= (8 - bit_num)
|
||||
print byte_acc.chr
|
||||
byte_acc = 0
|
||||
bit_num = 0
|
||||
end
|
||||
end
|
||||
end
|
564
benchmark/bm_so_meteor_contest.rb
Normal file
564
benchmark/bm_so_meteor_contest.rb
Normal file
|
@ -0,0 +1,564 @@
|
|||
#!/usr/bin/env ruby
|
||||
#
|
||||
# The Computer Language Shootout
|
||||
# http://shootout.alioth.debian.org
|
||||
# contributed by Kevin Barnes (Ruby novice)
|
||||
|
||||
# PROGRAM: the main body is at the bottom.
|
||||
# 1) read about the problem here: http://www-128.ibm.com/developerworks/java/library/j-javaopt/
|
||||
# 2) see how I represent a board as a bitmask by reading the blank_board comments
|
||||
# 3) read as your mental paths take you
|
||||
|
||||
def print *args
|
||||
end
|
||||
|
||||
# class to represent all information about a particular rotation of a particular piece
|
||||
class Rotation
|
||||
# an array (by location) containing a bit mask for how the piece maps at the given location.
|
||||
# if the rotation is illegal at that location the mask will contain false
|
||||
attr_reader :start_masks
|
||||
|
||||
# maps a direction to a relative location. these differ depending on whether it is an even or
|
||||
# odd row being mapped from
|
||||
@@rotation_even_adder = { :west => -1, :east => 1, :nw => -7, :ne => -6, :sw => 5, :se => 6 }
|
||||
@@rotation_odd_adder = { :west => -1, :east => 1, :nw => -6, :ne => -5, :sw => 6, :se => 7 }
|
||||
|
||||
def initialize( directions )
|
||||
@even_offsets, @odd_offsets = normalize_offsets( get_values( directions ))
|
||||
|
||||
@even_mask = mask_for_offsets( @even_offsets)
|
||||
@odd_mask = mask_for_offsets( @odd_offsets)
|
||||
|
||||
@start_masks = Array.new(60)
|
||||
|
||||
# create the rotational masks by placing the base mask at the location and seeing if
|
||||
# 1) it overlaps the boundries and 2) it produces a prunable board. if either of these
|
||||
# is true the piece cannot be placed
|
||||
0.upto(59) do | offset |
|
||||
mask = is_even(offset) ? (@even_mask << offset) : (@odd_mask << offset)
|
||||
if (blank_board & mask == 0 && !prunable(blank_board | mask, 0, true)) then
|
||||
imask = compute_required( mask, offset)
|
||||
@start_masks[offset] = [ mask, imask, imask | mask ]
|
||||
else
|
||||
@start_masks[offset] = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def compute_required( mask, offset )
|
||||
board = blank_board
|
||||
0.upto(offset) { | i | board |= 1 << i }
|
||||
board |= mask
|
||||
return 0 if (!prunable(board | mask, offset))
|
||||
board = flood_fill(board,58)
|
||||
count = 0
|
||||
imask = 0
|
||||
0.upto(59) do | i |
|
||||
if (board[i] == 0) then
|
||||
imask |= (1 << i)
|
||||
count += 1
|
||||
end
|
||||
end
|
||||
(count > 0 && count < 5) ? imask : 0
|
||||
end
|
||||
|
||||
def flood_fill( board, location)
|
||||
return board if (board[location] == 1)
|
||||
board |= 1 << location
|
||||
row, col = location.divmod(6)
|
||||
board = flood_fill( board, location - 1) if (col > 0)
|
||||
board = flood_fill( board, location + 1) if (col < 4)
|
||||
if (row % 2 == 0) then
|
||||
board = flood_fill( board, location - 7) if (col > 0 && row > 0)
|
||||
board = flood_fill( board, location - 6) if (row > 0)
|
||||
board = flood_fill( board, location + 6) if (row < 9)
|
||||
board = flood_fill( board, location + 5) if (col > 0 && row < 9)
|
||||
else
|
||||
board = flood_fill( board, location - 5) if (col < 4 && row > 0)
|
||||
board = flood_fill( board, location - 6) if (row > 0)
|
||||
board = flood_fill( board, location + 6) if (row < 9)
|
||||
board = flood_fill( board, location + 7) if (col < 4 && row < 9)
|
||||
end
|
||||
board
|
||||
end
|
||||
|
||||
# given a location, produces a list of relative locations covered by the piece at this rotation
|
||||
def offsets( location)
|
||||
if is_even( location) then
|
||||
@even_offsets.collect { | value | value + location }
|
||||
else
|
||||
@odd_offsets.collect { | value | value + location }
|
||||
end
|
||||
end
|
||||
|
||||
# returns a set of offsets relative to the top-left most piece of the rotation (by even or odd rows)
|
||||
# this is hard to explain. imagine we have this partial board:
|
||||
# 0 0 0 0 0 x [positions 0-5]
|
||||
# 0 0 1 1 0 x [positions 6-11]
|
||||
# 0 0 1 0 0 x [positions 12-17]
|
||||
# 0 1 0 0 0 x [positions 18-23]
|
||||
# 0 1 0 0 0 x [positions 24-29]
|
||||
# 0 0 0 0 0 x [positions 30-35]
|
||||
# ...
|
||||
# The top-left of the piece is at position 8, the
|
||||
# board would be passed as a set of positions (values array) containing [8,9,14,19,25] not necessarily in that
|
||||
# sorted order. Since that array starts on an odd row, the offsets for an odd row are: [0,1,6,11,17] obtained
|
||||
# by subtracting 8 from everything. Now imagine the piece shifted up and to the right so it's on an even row:
|
||||
# 0 0 0 1 1 x [positions 0-5]
|
||||
# 0 0 1 0 0 x [positions 6-11]
|
||||
# 0 0 1 0 0 x [positions 12-17]
|
||||
# 0 1 0 0 0 x [positions 18-23]
|
||||
# 0 0 0 0 0 x [positions 24-29]
|
||||
# 0 0 0 0 0 x [positions 30-35]
|
||||
# ...
|
||||
# Now the positions are [3,4,8,14,19] which after subtracting the lowest value (3) gives [0,1,5,11,16] thus, the
|
||||
# offsets for this particular piece are (in even, odd order) [0,1,5,11,16],[0,1,6,11,17] which is what
|
||||
# this function would return
|
||||
def normalize_offsets( values)
|
||||
min = values.min
|
||||
even_min = is_even(min)
|
||||
other_min = even_min ? min + 6 : min + 7
|
||||
other_values = values.collect do | value |
|
||||
if is_even(value) then
|
||||
value + 6 - other_min
|
||||
else
|
||||
value + 7 - other_min
|
||||
end
|
||||
end
|
||||
values.collect! { | value | value - min }
|
||||
|
||||
if even_min then
|
||||
[values, other_values]
|
||||
else
|
||||
[other_values, values]
|
||||
end
|
||||
end
|
||||
|
||||
# produce a bitmask representation of an array of offset locations
|
||||
def mask_for_offsets( offsets )
|
||||
mask = 0
|
||||
offsets.each { | value | mask = mask + ( 1 << value ) }
|
||||
mask
|
||||
end
|
||||
|
||||
# finds a "safe" position that a position as described by a list of directions can be placed
|
||||
# without falling off any edge of the board. the values returned a location to place the first piece
|
||||
# at so it will fit after making the described moves
|
||||
def start_adjust( directions )
|
||||
south = east = 0;
|
||||
directions.each do | direction |
|
||||
east += 1 if ( direction == :sw || direction == :nw || direction == :west )
|
||||
south += 1 if ( direction == :nw || direction == :ne )
|
||||
end
|
||||
south * 6 + east
|
||||
end
|
||||
|
||||
# given a set of directions places the piece (as defined by a set of directions) on the board at
|
||||
# a location that will not take it off the edge
|
||||
def get_values ( directions )
|
||||
start = start_adjust(directions)
|
||||
values = [ start ]
|
||||
directions.each do | direction |
|
||||
if (start % 12 >= 6) then
|
||||
start += @@rotation_odd_adder[direction]
|
||||
else
|
||||
start += @@rotation_even_adder[direction]
|
||||
end
|
||||
values += [ start ]
|
||||
end
|
||||
|
||||
# some moves take you back to an existing location, we'll strip duplicates
|
||||
values.uniq
|
||||
end
|
||||
end
|
||||
|
||||
# describes a piece and caches information about its rotations to as to be efficient for iteration
|
||||
# ATTRIBUTES:
|
||||
# rotations -- all the rotations of the piece
|
||||
# type -- a numeic "name" of the piece
|
||||
# masks -- an array by location of all legal rotational masks (a n inner array) for that location
|
||||
# placed -- the mask that this piece was last placed at (not a location, but the actual mask used)
|
||||
class Piece
|
||||
attr_reader :rotations, :type, :masks
|
||||
attr_accessor :placed
|
||||
|
||||
# transform hashes that change one direction into another when you either flip or rotate a set of directions
|
||||
@@flip_converter = { :west => :west, :east => :east, :nw => :sw, :ne => :se, :sw => :nw, :se => :ne }
|
||||
@@rotate_converter = { :west => :nw, :east => :se, :nw => :ne, :ne => :east, :sw => :west, :se => :sw }
|
||||
|
||||
def initialize( directions, type )
|
||||
@type = type
|
||||
@rotations = Array.new();
|
||||
@map = {}
|
||||
|
||||
generate_rotations( directions )
|
||||
directions.collect! { | value | @@flip_converter[value] }
|
||||
generate_rotations( directions )
|
||||
|
||||
# creates the masks AND a map that returns [location, rotation] for any given mask
|
||||
# this is used when a board is found and we want to draw it, otherwise the map is unused
|
||||
@masks = Array.new();
|
||||
0.upto(59) do | i |
|
||||
even = true
|
||||
@masks[i] = @rotations.collect do | rotation |
|
||||
mask = rotation.start_masks[i]
|
||||
@map[mask[0]] = [ i, rotation ] if (mask)
|
||||
mask || nil
|
||||
end
|
||||
@masks[i].compact!
|
||||
end
|
||||
end
|
||||
|
||||
# rotates a set of directions through all six angles and adds a Rotation to the list for each one
|
||||
def generate_rotations( directions )
|
||||
6.times do
|
||||
rotations.push( Rotation.new(directions))
|
||||
directions.collect! { | value | @@rotate_converter[value] }
|
||||
end
|
||||
end
|
||||
|
||||
# given a board string, adds this piece to the board at whatever location/rotation
|
||||
# important: the outbound board string is 5 wide, the normal location notation is six wide (padded)
|
||||
def fill_string( board_string)
|
||||
location, rotation = @map[@placed]
|
||||
rotation.offsets(location).each do | offset |
|
||||
row, col = offset.divmod(6)
|
||||
board_string[ row*5 + col, 1 ] = @type.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# a blank bit board having this form:
|
||||
#
|
||||
# 0 0 0 0 0 1
|
||||
# 0 0 0 0 0 1
|
||||
# 0 0 0 0 0 1
|
||||
# 0 0 0 0 0 1
|
||||
# 0 0 0 0 0 1
|
||||
# 0 0 0 0 0 1
|
||||
# 0 0 0 0 0 1
|
||||
# 0 0 0 0 0 1
|
||||
# 0 0 0 0 0 1
|
||||
# 0 0 0 0 0 1
|
||||
# 1 1 1 1 1 1
|
||||
#
|
||||
# where left lest significant bit is the top left and the most significant is the lower right
|
||||
# the actual board only consists of the 0 places, the 1 places are blockers to keep things from running
|
||||
# off the edges or bottom
|
||||
def blank_board
|
||||
0b111111100000100000100000100000100000100000100000100000100000100000
|
||||
end
|
||||
|
||||
def full_board
|
||||
0b111111111111111111111111111111111111111111111111111111111111111111
|
||||
end
|
||||
|
||||
# determines if a location (bit position) is in an even row
|
||||
def is_even( location)
|
||||
(location % 12) < 6
|
||||
end
|
||||
|
||||
# support function that create three utility maps:
|
||||
# $converter -- for each row an array that maps a five bit row (via array mapping)
|
||||
# to the a a five bit representation of the bits below it
|
||||
# $bit_count -- maps a five bit row (via array mapping) to the number of 1s in the row
|
||||
# @@new_regions -- maps a five bit row (via array mapping) to an array of "region" arrays
|
||||
# a region array has three values the first is a mask of bits in the region,
|
||||
# the second is the count of those bits and the third is identical to the first
|
||||
# examples:
|
||||
# 0b10010 => [ 0b01100, 2, 0b01100 ], [ 0b00001, 1, 0b00001]
|
||||
# 0b01010 => [ 0b10000, 1, 0b10000 ], [ 0b00100, 1, 0b00100 ], [ 0b00001, 1, 0b00001]
|
||||
# 0b10001 => [ 0b01110, 3, 0b01110 ]
|
||||
def create_collector_support
|
||||
odd_map = [0b11, 0b110, 0b1100, 0b11000, 0b10000]
|
||||
even_map = [0b1, 0b11, 0b110, 0b1100, 0b11000]
|
||||
|
||||
all_odds = Array.new(0b100000)
|
||||
all_evens = Array.new(0b100000)
|
||||
bit_counts = Array.new(0b100000)
|
||||
new_regions = Array.new(0b100000)
|
||||
0.upto(0b11111) do | i |
|
||||
bit_count = odd = even = 0
|
||||
0.upto(4) do | bit |
|
||||
if (i[bit] == 1) then
|
||||
bit_count += 1
|
||||
odd |= odd_map[bit]
|
||||
even |= even_map[bit]
|
||||
end
|
||||
end
|
||||
all_odds[i] = odd
|
||||
all_evens[i] = even
|
||||
bit_counts[i] = bit_count
|
||||
new_regions[i] = create_regions( i)
|
||||
end
|
||||
|
||||
$converter = []
|
||||
10.times { | row | $converter.push((row % 2 == 0) ? all_evens : all_odds) }
|
||||
$bit_counts = bit_counts
|
||||
$regions = new_regions.collect { | set | set.collect { | value | [ value, bit_counts[value], value] } }
|
||||
end
|
||||
|
||||
# determines if a board is punable, meaning that there is no possibility that it
|
||||
# can be filled up with pieces. A board is prunable if there is a grouping of unfilled spaces
|
||||
# that are not a multiple of five. The following board is an example of a prunable board:
|
||||
# 0 0 1 0 0
|
||||
# 0 1 0 0 0
|
||||
# 1 1 0 0 0
|
||||
# 0 1 0 0 0
|
||||
# 0 0 0 0 0
|
||||
# ...
|
||||
#
|
||||
# This board is prunable because the top left corner is only 3 bits in area, no piece will ever fit it
|
||||
# parameters:
|
||||
# board -- an initial bit board (6 bit padded rows, see blank_board for format)
|
||||
# location -- starting location, everything above and to the left is already full
|
||||
# slotting -- set to true only when testing initial pieces, when filling normally
|
||||
# additional assumptions are possible
|
||||
#
|
||||
# Algorithm:
|
||||
# The algorithm starts at the top row (as determined by location) and iterates a row at a time
|
||||
# maintainng counts of active open areas (kept in the collector array) each collector contains
|
||||
# three values at the start of an iteration:
|
||||
# 0: mask of bits that would be adjacent to the collector in this row
|
||||
# 1: the number of bits collected so far
|
||||
# 2: a scratch space starting as zero, but used during the computation to represent
|
||||
# the empty bits in the new row that are adjacent (position 0)
|
||||
# The exact procedure is described in-code
|
||||
def prunable( board, location, slotting = false)
|
||||
collectors = []
|
||||
# loop accross the rows
|
||||
(location / 6).to_i.upto(9) do | row_on |
|
||||
# obtain a set of regions representing the bits of the curent row.
|
||||
regions = $regions[(board >> (row_on * 6)) & 0b11111]
|
||||
converter = $converter[row_on]
|
||||
|
||||
# track the number of collectors at the start of the cycle so that
|
||||
# we don't compute against newly created collectors, only existing collectors
|
||||
initial_collector_count = collectors.length
|
||||
|
||||
# loop against the regions. For each region of the row
|
||||
# we will see if it connects to one or more existing collectors.
|
||||
# if it connects to 1 collector, the bits from the region are added to the
|
||||
# bits of the collector and the mask is placed in collector[2]
|
||||
# If the region overlaps more than one collector then all the collectors
|
||||
# it overlaps with are merged into the first one (the others are set to nil in the array)
|
||||
# if NO collectors are found then the region is copied as a new collector
|
||||
regions.each do | region |
|
||||
collector_found = nil
|
||||
region_mask = region[2]
|
||||
initial_collector_count.times do | collector_num |
|
||||
collector = collectors[collector_num]
|
||||
if (collector) then
|
||||
collector_mask = collector[0]
|
||||
if (collector_mask & region_mask != 0) then
|
||||
if (collector_found) then
|
||||
collector_found[0] |= collector_mask
|
||||
collector_found[1] += collector[1]
|
||||
collector_found[2] |= collector[2]
|
||||
collectors[collector_num] = nil
|
||||
else
|
||||
collector_found = collector
|
||||
collector[1] += region[1]
|
||||
collector[2] |= region_mask
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if (collector_found == nil) then
|
||||
collectors.push(Array.new(region))
|
||||
end
|
||||
end
|
||||
|
||||
# check the existing collectors, if any collector overlapped no bits in the region its [2] value will
|
||||
# be zero. The size of any such reaason is tested if it is not a muliple of five true is returned since
|
||||
# the board is prunable. if it is a multiple of five it is removed.
|
||||
# Collector that are still active have a new adjacent value [0] set based n the matched bits
|
||||
# and have [2] cleared out for the next cycle.
|
||||
collectors.length.times do | collector_num |
|
||||
collector = collectors[collector_num]
|
||||
if (collector) then
|
||||
if (collector[2] == 0) then
|
||||
return true if (collector[1] % 5 != 0)
|
||||
collectors[collector_num] = nil
|
||||
else
|
||||
# if a collector matches all bits in the row then we can return unprunable early for the
|
||||
# follwing reasons:
|
||||
# 1) there can be no more unavailable bits bince we fill from the top left downward
|
||||
# 2) all previous regions have been closed or joined so only this region can fail
|
||||
# 3) this region must be good since there can never be only 1 region that is nuot
|
||||
# a multiple of five
|
||||
# this rule only applies when filling normally, so we ignore the rule if we are "slotting"
|
||||
# in pieces to see what configurations work for them (the only other time this algorithm is used).
|
||||
return false if (collector[2] == 0b11111 && !slotting)
|
||||
collector[0] = converter[collector[2]]
|
||||
collector[2] = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# get rid of all the empty converters for the next round
|
||||
collectors.compact!
|
||||
end
|
||||
return false if (collectors.length <= 1) # 1 collector or less and the region is fine
|
||||
collectors.any? { | collector | (collector[1] % 5) != 0 } # more than 1 and we test them all for bad size
|
||||
end
|
||||
|
||||
# creates a region given a row mask. see prunable for what a "region" is
|
||||
def create_regions( value )
|
||||
regions = []
|
||||
cur_region = 0
|
||||
5.times do | bit |
|
||||
if (value[bit] == 0) then
|
||||
cur_region |= 1 << bit
|
||||
else
|
||||
if (cur_region != 0 ) then
|
||||
regions.push( cur_region)
|
||||
cur_region = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
regions.push(cur_region) if (cur_region != 0)
|
||||
regions
|
||||
end
|
||||
|
||||
# find up to the counted number of solutions (or all solutions) and prints the final result
|
||||
def find_all
|
||||
find_top( 1)
|
||||
find_top( 0)
|
||||
print_results
|
||||
end
|
||||
|
||||
# show the board
|
||||
def print_results
|
||||
print "#{@boards_found} solutions found\n\n"
|
||||
print_full_board( @min_board)
|
||||
print "\n"
|
||||
print_full_board( @max_board)
|
||||
print "\n"
|
||||
end
|
||||
|
||||
# finds solutions. This special version of the main function is only used for the top level
|
||||
# the reason for it is basically to force a particular ordering on how the rotations are tested for
|
||||
# the first piece. It is called twice, first looking for placements of the odd rotations and then
|
||||
# looking for placements of the even locations.
|
||||
#
|
||||
# WHY?
|
||||
# Since any found solution has an inverse we want to maximize finding solutions that are not already found
|
||||
# as an inverse. The inverse will ALWAYS be 3 one of the piece configurations that is exactly 3 rotations away
|
||||
# (an odd number). Checking even vs odd then produces a higher probability of finding more pieces earlier
|
||||
# in the cycle. We still need to keep checking all the permutations, but our probability of finding one will
|
||||
# diminsh over time. Since we are TOLD how many to search for this lets us exit before checking all pieces
|
||||
# this bennifit is very great when seeking small numbers of solutions and is 0 when looking for more than the
|
||||
# maximum number
|
||||
def find_top( rotation_skip)
|
||||
board = blank_board
|
||||
(@pieces.length-1).times do
|
||||
piece = @pieces.shift
|
||||
piece.masks[0].each do | mask, imask, cmask |
|
||||
if ((rotation_skip += 1) % 2 == 0) then
|
||||
piece.placed = mask
|
||||
find( 1, 1, board | mask)
|
||||
end
|
||||
end
|
||||
@pieces.push(piece)
|
||||
end
|
||||
piece = @pieces.shift
|
||||
@pieces.push(piece)
|
||||
end
|
||||
|
||||
# the normail find routine, iterates through the available pieces, checks all rotations at the current location
|
||||
# and adds any boards found. depth is acheived via recursion. the overall approach is described
|
||||
# here: http://www-128.ibm.com/developerworks/java/library/j-javaopt/
|
||||
# parameters:
|
||||
# start_location -- where to start looking for place for the next piece at
|
||||
# placed -- number of pieces placed
|
||||
# board -- current state of the board
|
||||
#
|
||||
# see in-code comments
|
||||
def find( start_location, placed, board)
|
||||
# find the next location to place a piece by looking for an empty bit
|
||||
while board[start_location] == 1
|
||||
start_location += 1
|
||||
end
|
||||
|
||||
@pieces.length.times do
|
||||
piece = @pieces.shift
|
||||
piece.masks[start_location].each do | mask, imask, cmask |
|
||||
if ( board & cmask == imask) then
|
||||
piece.placed = mask
|
||||
if (placed == 9) then
|
||||
add_board
|
||||
else
|
||||
find( start_location + 1, placed + 1, board | mask)
|
||||
end
|
||||
end
|
||||
end
|
||||
@pieces.push(piece)
|
||||
end
|
||||
end
|
||||
|
||||
# print the board
|
||||
def print_full_board( board_string)
|
||||
10.times do | row |
|
||||
print " " if (row % 2 == 1)
|
||||
5.times do | col |
|
||||
print "#{board_string[row*5 + col,1]} "
|
||||
end
|
||||
print "\n"
|
||||
end
|
||||
end
|
||||
|
||||
# when a board is found we "draw it" into a string and then flip that string, adding both to
|
||||
# the list (hash) of solutions if they are unique.
|
||||
def add_board
|
||||
board_string = "99999999999999999999999999999999999999999999999999"
|
||||
@all_pieces.each { | piece | piece.fill_string( board_string ) }
|
||||
save( board_string)
|
||||
save( board_string.reverse)
|
||||
end
|
||||
|
||||
# adds a board string to the list (if new) and updates the current best/worst board
|
||||
def save( board_string)
|
||||
if (@all_boards[board_string] == nil) then
|
||||
@min_board = board_string if (board_string < @min_board)
|
||||
@max_board = board_string if (board_string > @max_board)
|
||||
@all_boards.store(board_string,true)
|
||||
@boards_found += 1
|
||||
|
||||
# the exit motif is a time saver. Ideally the function should return, but those tests
|
||||
# take noticable time (performance).
|
||||
if (@boards_found == @stop_count) then
|
||||
print_results
|
||||
exit(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
##
|
||||
## MAIN BODY :)
|
||||
##
|
||||
create_collector_support
|
||||
@pieces = [
|
||||
Piece.new( [ :nw, :ne, :east, :east ], 2),
|
||||
Piece.new( [ :ne, :se, :east, :ne ], 7),
|
||||
Piece.new( [ :ne, :east, :ne, :nw ], 1),
|
||||
Piece.new( [ :east, :sw, :sw, :se ], 6),
|
||||
Piece.new( [ :east, :ne, :se, :ne ], 5),
|
||||
Piece.new( [ :east, :east, :east, :se ], 0),
|
||||
Piece.new( [ :ne, :nw, :se, :east, :se ], 4),
|
||||
Piece.new( [ :se, :se, :se, :west ], 9),
|
||||
Piece.new( [ :se, :se, :east, :se ], 8),
|
||||
Piece.new( [ :east, :east, :sw, :se ], 3)
|
||||
];
|
||||
|
||||
@all_pieces = Array.new( @pieces)
|
||||
|
||||
@min_board = "99999999999999999999999999999999999999999999999999"
|
||||
@max_board = "00000000000000000000000000000000000000000000000000"
|
||||
@stop_count = ARGV[0].to_i || 2089
|
||||
@all_boards = {}
|
||||
@boards_found = 0
|
||||
|
||||
find_all ######## DO IT!!!
|
||||
|
148
benchmark/bm_so_nbody.rb
Normal file
148
benchmark/bm_so_nbody.rb
Normal file
|
@ -0,0 +1,148 @@
|
|||
# The Computer Language Shootout
|
||||
# http://shootout.alioth.debian.org
|
||||
#
|
||||
# Optimized for Ruby by Jesse Millikan
|
||||
# From version ported by Michael Neumann from the C gcc version,
|
||||
# which was written by Christoph Bauer.
|
||||
|
||||
SOLAR_MASS = 4 * Math::PI**2
|
||||
DAYS_PER_YEAR = 365.24
|
||||
|
||||
def _puts *args
|
||||
end
|
||||
|
||||
class Planet
|
||||
attr_accessor :x, :y, :z, :vx, :vy, :vz, :mass
|
||||
|
||||
def initialize(x, y, z, vx, vy, vz, mass)
|
||||
@x, @y, @z = x, y, z
|
||||
@vx, @vy, @vz = vx * DAYS_PER_YEAR, vy * DAYS_PER_YEAR, vz * DAYS_PER_YEAR
|
||||
@mass = mass * SOLAR_MASS
|
||||
end
|
||||
|
||||
def move_from_i(bodies, nbodies, dt, i)
|
||||
while i < nbodies
|
||||
b2 = bodies[i]
|
||||
dx = @x - b2.x
|
||||
dy = @y - b2.y
|
||||
dz = @z - b2.z
|
||||
|
||||
distance = Math.sqrt(dx * dx + dy * dy + dz * dz)
|
||||
mag = dt / (distance * distance * distance)
|
||||
b_mass_mag, b2_mass_mag = @mass * mag, b2.mass * mag
|
||||
|
||||
@vx -= dx * b2_mass_mag
|
||||
@vy -= dy * b2_mass_mag
|
||||
@vz -= dz * b2_mass_mag
|
||||
b2.vx += dx * b_mass_mag
|
||||
b2.vy += dy * b_mass_mag
|
||||
b2.vz += dz * b_mass_mag
|
||||
i += 1
|
||||
end
|
||||
|
||||
@x += dt * @vx
|
||||
@y += dt * @vy
|
||||
@z += dt * @vz
|
||||
end
|
||||
end
|
||||
|
||||
def energy(bodies)
|
||||
e = 0.0
|
||||
nbodies = bodies.size
|
||||
|
||||
for i in 0 ... nbodies
|
||||
b = bodies[i]
|
||||
e += 0.5 * b.mass * (b.vx * b.vx + b.vy * b.vy + b.vz * b.vz)
|
||||
for j in (i + 1) ... nbodies
|
||||
b2 = bodies[j]
|
||||
dx = b.x - b2.x
|
||||
dy = b.y - b2.y
|
||||
dz = b.z - b2.z
|
||||
distance = Math.sqrt(dx * dx + dy * dy + dz * dz)
|
||||
e -= (b.mass * b2.mass) / distance
|
||||
end
|
||||
end
|
||||
e
|
||||
end
|
||||
|
||||
def offset_momentum(bodies)
|
||||
px, py, pz = 0.0, 0.0, 0.0
|
||||
|
||||
for b in bodies
|
||||
m = b.mass
|
||||
px += b.vx * m
|
||||
py += b.vy * m
|
||||
pz += b.vz * m
|
||||
end
|
||||
|
||||
b = bodies[0]
|
||||
b.vx = - px / SOLAR_MASS
|
||||
b.vy = - py / SOLAR_MASS
|
||||
b.vz = - pz / SOLAR_MASS
|
||||
end
|
||||
|
||||
BODIES = [
|
||||
# sun
|
||||
Planet.new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0),
|
||||
|
||||
# jupiter
|
||||
Planet.new(
|
||||
4.84143144246472090e+00,
|
||||
-1.16032004402742839e+00,
|
||||
-1.03622044471123109e-01,
|
||||
1.66007664274403694e-03,
|
||||
7.69901118419740425e-03,
|
||||
-6.90460016972063023e-05,
|
||||
9.54791938424326609e-04),
|
||||
|
||||
# saturn
|
||||
Planet.new(
|
||||
8.34336671824457987e+00,
|
||||
4.12479856412430479e+00,
|
||||
-4.03523417114321381e-01,
|
||||
-2.76742510726862411e-03,
|
||||
4.99852801234917238e-03,
|
||||
2.30417297573763929e-05,
|
||||
2.85885980666130812e-04),
|
||||
|
||||
# uranus
|
||||
Planet.new(
|
||||
1.28943695621391310e+01,
|
||||
-1.51111514016986312e+01,
|
||||
-2.23307578892655734e-01,
|
||||
2.96460137564761618e-03,
|
||||
2.37847173959480950e-03,
|
||||
-2.96589568540237556e-05,
|
||||
4.36624404335156298e-05),
|
||||
|
||||
# neptune
|
||||
Planet.new(
|
||||
1.53796971148509165e+01,
|
||||
-2.59193146099879641e+01,
|
||||
1.79258772950371181e-01,
|
||||
2.68067772490389322e-03,
|
||||
1.62824170038242295e-03,
|
||||
-9.51592254519715870e-05,
|
||||
5.15138902046611451e-05)
|
||||
]
|
||||
|
||||
init = 200_000 # ARGV[0]
|
||||
n = Integer(init)
|
||||
|
||||
offset_momentum(BODIES)
|
||||
|
||||
puts "%.9f" % energy(BODIES)
|
||||
|
||||
nbodies = BODIES.size
|
||||
dt = 0.01
|
||||
|
||||
n.times do
|
||||
i = 0
|
||||
while i < nbodies
|
||||
b = BODIES[i]
|
||||
b.move_from_i(BODIES, nbodies, dt, i + 1)
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
|
||||
puts "%.9f" % energy(BODIES)
|
35
benchmark/bm_so_nsieve.rb
Normal file
35
benchmark/bm_so_nsieve.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
# The Computer Language Shootout
|
||||
# http://shootout.alioth.debian.org/
|
||||
#
|
||||
# contributed by Glenn Parker, March 2005
|
||||
# modified by Evan Phoenix, Sept 2006
|
||||
|
||||
def sieve(m)
|
||||
flags = Flags.dup[0,m]
|
||||
count = 0
|
||||
pmax = m - 1
|
||||
p = 2
|
||||
while p <= pmax
|
||||
unless flags[p].zero?
|
||||
count += 1
|
||||
mult = p
|
||||
while mult <= pmax
|
||||
flags[mult] = 0
|
||||
mult += p
|
||||
end
|
||||
end
|
||||
p += 1
|
||||
end
|
||||
count
|
||||
end
|
||||
|
||||
n = 9 # (ARGV[0] || 2).to_i
|
||||
Flags = ("\x1" * ( 2 ** n * 10_000)).unpack("c*")
|
||||
|
||||
n.downto(n-2) do |exponent|
|
||||
break if exponent < 0
|
||||
m = (1 << exponent) * 10_000
|
||||
# m = (2 ** exponent) * 10_000
|
||||
count = sieve(m)
|
||||
printf "Primes up to %8d %8d\n", m, count
|
||||
end
|
42
benchmark/bm_so_nsieve_bits.rb
Normal file
42
benchmark/bm_so_nsieve_bits.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/ruby
|
||||
#
|
||||
# The Great Computer Language Shootout
|
||||
# http://shootout.alioth.debian.org/
|
||||
#
|
||||
# nsieve-bits in Ruby
|
||||
# Contributed by Glenn Parker, March 2005
|
||||
|
||||
CharExponent = 3
|
||||
BitsPerChar = 1 << CharExponent
|
||||
LowMask = BitsPerChar - 1
|
||||
|
||||
def sieve(m)
|
||||
items = "\xFF" * ((m / BitsPerChar) + 1)
|
||||
masks = ""
|
||||
BitsPerChar.times do |b|
|
||||
masks << (1 << b).chr
|
||||
end
|
||||
|
||||
count = 0
|
||||
pmax = m - 1
|
||||
2.step(pmax, 1) do |p|
|
||||
if items[p >> CharExponent][p & LowMask] == 1
|
||||
count += 1
|
||||
p.step(pmax, p) do |mult|
|
||||
a = mult >> CharExponent
|
||||
b = mult & LowMask
|
||||
items[a] -= masks[b] if items[a][b] != 0
|
||||
end
|
||||
end
|
||||
end
|
||||
count
|
||||
end
|
||||
|
||||
n = 9 # (ARGV[0] || 2).to_i
|
||||
n.step(n - 2, -1) do |exponent|
|
||||
break if exponent < 0
|
||||
m = 2 ** exponent * 10_000
|
||||
count = sieve(m)
|
||||
printf "Primes up to %8d %8d\n", m, count
|
||||
end
|
||||
|
31
benchmark/bm_so_partial_sums.rb
Normal file
31
benchmark/bm_so_partial_sums.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
n = 2_500_000 # (ARGV.shift || 1).to_i
|
||||
|
||||
alt = 1.0 ; s0 = s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = 0.0
|
||||
|
||||
1.upto(n) do |d|
|
||||
d = d.to_f ; d2 = d * d ; d3 = d2 * d ; ds = Math.sin(d) ; dc = Math.cos(d)
|
||||
|
||||
s0 += (2.0 / 3.0) ** (d - 1.0)
|
||||
s1 += 1.0 / Math.sqrt(d)
|
||||
s2 += 1.0 / (d * (d + 1.0))
|
||||
s3 += 1.0 / (d3 * ds * ds)
|
||||
s4 += 1.0 / (d3 * dc * dc)
|
||||
s5 += 1.0 / d
|
||||
s6 += 1.0 / d2
|
||||
s7 += alt / d
|
||||
s8 += alt / (2.0 * d - 1.0)
|
||||
|
||||
alt = -alt
|
||||
end
|
||||
|
||||
if false
|
||||
printf("%.9f\t(2/3)^k\n", s0)
|
||||
printf("%.9f\tk^-0.5\n", s1)
|
||||
printf("%.9f\t1/k(k+1)\n", s2)
|
||||
printf("%.9f\tFlint Hills\n", s3)
|
||||
printf("%.9f\tCookson Hills\n", s4)
|
||||
printf("%.9f\tHarmonic\n", s5)
|
||||
printf("%.9f\tRiemann Zeta\n", s6)
|
||||
printf("%.9f\tAlternating Harmonic\n", s7)
|
||||
printf("%.9f\tGregory\n", s8)
|
||||
end
|
92
benchmark/bm_so_pidigits.rb
Normal file
92
benchmark/bm_so_pidigits.rb
Normal file
|
@ -0,0 +1,92 @@
|
|||
# The Great Computer Language Shootout
|
||||
# http://shootout.alioth.debian.org/
|
||||
#
|
||||
# contributed by Gabriele Renzi
|
||||
|
||||
class PiDigitSpigot
|
||||
|
||||
def initialize()
|
||||
@z = Transformation.new 1,0,0,1
|
||||
@x = Transformation.new 0,0,0,0
|
||||
@inverse = Transformation.new 0,0,0,0
|
||||
end
|
||||
|
||||
def next!
|
||||
@y = @z.extract(3)
|
||||
if safe? @y
|
||||
@z = produce(@y)
|
||||
@y
|
||||
else
|
||||
@z = consume @x.next!()
|
||||
next!()
|
||||
end
|
||||
end
|
||||
|
||||
def safe?(digit)
|
||||
digit == @z.extract(4)
|
||||
end
|
||||
|
||||
def produce(i)
|
||||
@inverse.qrst(10,-10*i,0,1).compose(@z)
|
||||
end
|
||||
|
||||
def consume(a)
|
||||
@z.compose(a)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class Transformation
|
||||
attr_reader :q, :r, :s, :t
|
||||
def initialize (q, r, s, t)
|
||||
@q,@r,@s,@t,@k = q,r,s,t,0
|
||||
end
|
||||
|
||||
def next!()
|
||||
@q = @k = @k + 1
|
||||
@r = 4 * @k + 2
|
||||
@s = 0
|
||||
@t = 2 * @k + 1
|
||||
self
|
||||
end
|
||||
|
||||
def extract(j)
|
||||
(@q * j + @r) / (@s * j + @t)
|
||||
end
|
||||
|
||||
def compose(a)
|
||||
self.class.new( @q * a.q,
|
||||
@q * a.r + r * a.t,
|
||||
@s * a.q + t * a.s,
|
||||
@s * a.r + t * a.t
|
||||
)
|
||||
end
|
||||
|
||||
def qrst *args
|
||||
initialize *args
|
||||
self
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
WIDTH = 10
|
||||
n = 2_500 # Integer(ARGV[0])
|
||||
j = 0
|
||||
|
||||
digits = PiDigitSpigot.new
|
||||
|
||||
while n > 0
|
||||
if n >= WIDTH
|
||||
WIDTH.times {print digits.next!}
|
||||
j += WIDTH
|
||||
else
|
||||
n.times {print digits.next!}
|
||||
(WIDTH-n).times {print " "}
|
||||
j += n
|
||||
end
|
||||
puts "\t:"+j.to_s
|
||||
n -= WIDTH
|
||||
end
|
||||
|
50
benchmark/bm_so_spectralnorm.rb
Normal file
50
benchmark/bm_so_spectralnorm.rb
Normal file
|
@ -0,0 +1,50 @@
|
|||
# The Computer Language Shootout
|
||||
# http://shootout.alioth.debian.org/
|
||||
# Contributed by Sokolov Yura
|
||||
|
||||
def eval_A(i,j)
|
||||
return 1.0/((i+j)*(i+j+1)/2+i+1)
|
||||
end
|
||||
|
||||
def eval_A_times_u(u)
|
||||
v, i = nil, nil
|
||||
(0..u.length-1).collect { |i|
|
||||
v = 0
|
||||
for j in 0..u.length-1
|
||||
v += eval_A(i,j)*u[j]
|
||||
end
|
||||
v
|
||||
}
|
||||
end
|
||||
|
||||
def eval_At_times_u(u)
|
||||
v, i = nil, nil
|
||||
(0..u.length-1).collect{|i|
|
||||
v = 0
|
||||
for j in 0..u.length-1
|
||||
v += eval_A(j,i)*u[j]
|
||||
end
|
||||
v
|
||||
}
|
||||
end
|
||||
|
||||
def eval_AtA_times_u(u)
|
||||
return eval_At_times_u(eval_A_times_u(u))
|
||||
end
|
||||
|
||||
n = 500 # ARGV[0].to_i
|
||||
|
||||
u=[1]*n
|
||||
for i in 1..10
|
||||
v=eval_AtA_times_u(u)
|
||||
u=eval_AtA_times_u(v)
|
||||
end
|
||||
vBv=0
|
||||
vv=0
|
||||
for i in 0..n-1
|
||||
vBv += u[i]*v[i]
|
||||
vv += v[i]*v[i]
|
||||
end
|
||||
|
||||
str = "%0.9f" % (Math.sqrt(vBv/vv)), "\n"
|
||||
# print str
|
6
benchmark/bm_vm1_ivar_set.rb
Normal file
6
benchmark/bm_vm1_ivar_set.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
i = 0
|
||||
while i<30_000_000 # while loop 1
|
||||
i+= 1
|
||||
@a = 1
|
||||
@b = 2
|
||||
end
|
|
@ -77,6 +77,7 @@ class BenchmarkDriver
|
|||
if @verbose
|
||||
message '-----------------------------------------------------------'
|
||||
message 'raw data:'
|
||||
message
|
||||
message PP.pp(@results, "", 79)
|
||||
message
|
||||
message "Elapesed time: #{Time.now - @start_time} (sec)"
|
||||
|
@ -158,6 +159,7 @@ class BenchmarkDriver
|
|||
output
|
||||
output '-----------------------------------------------------------'
|
||||
output name
|
||||
output
|
||||
output File.read(file)
|
||||
output
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue