pax_global_header 0000666 0000000 0000000 00000000064 12272751743 0014524 g ustar 00root root 0000000 0000000 52 comment=ce2c9ff04b5e0d610c86e97af19d59b59894830f
ruby-numru-misc-0.1.1/ 0000775 0000000 0000000 00000000000 12272751743 0014601 5 ustar 00root root 0000000 0000000 ruby-numru-misc-0.1.1/ChangeLog 0000664 0000000 0000000 00000002745 12272751743 0016363 0 ustar 00root root 0000000 0000000 Mon Aug 11 2011 T Horinouchi
* numru-misc-0.1.1 released (relase tag: numru-misc-0_1_1)
* LICENCE.txt: Added (BSD 2-clause licence)
Mon Mar 15 2010 T Horinouchi
* numru-misc-0.1.0 released (relase tag: numru-misc-0_1_0)
2008-02-05 S Otsuka
* install.rb: for ruby 1.9
Fri May 13 2005 T Horinouchi
* numru-misc-0.0.6 released (relase tag: numru-misc-0_0_6)
* keywordopt.rb: KeywordOpt#keys --> public (returns @keys.dup).
Added KeywordOpt#select_keys.
Tue Aug 12 2004 T Horinouchi
* keywordopt.rb: modified KeywordOptAutoHelp#set to show help
message if 'help'==true.
Tue Aug 10 2004 T Horinouchi
* numru-misc-0.0.5 released (relase tag: numru-misc-0_0_5)
* package renamed from misc to numru-misc: started new CVS
Fri Mar 19 2004 T Horinouchi
* emath.rb: basically, a refactoring
* install.rb: debug
Wed Dec 10 2003 T Horinouchi
* misc-0.0.4 released
* emath.rb: NumRu::EMath --> NumRu::Misc::EMath
Documentation.
* misc.rb: documentation update for EMath.
Tue Oct 7 2003 T Horinouchi
* emath.rb: created
Mon Sep 1 2003 T Horinouchi
* misc-0.0.3 released
* keywordopt.rb: minor debug of the help messaging in
KeywordOptAutoHelp#interpret
Tue Aug 26 2003 T Horinouchi
* keywordopt.rb: added class KeywordOptAutoHelp. refined help.
allowed KeywordOpt.new to accept another KeywordOpt.
Mon Aug 25 2003 T Horinouchi
* keywordopt.rb: KeywordOpt#interpret slightly modified
Mon Aug 25 2003 T Horinouchi
* version 0.0.2 released
ruby-numru-misc-0.1.1/LICENSE.txt 0000664 0000000 0000000 00000003263 12272751743 0016430 0 ustar 00root root 0000000 0000000 NumRu::Misc is copyrighted free software by Takeshi Horinouchi and
GFD Dennou Club (http://www.gfd-dennou.org/).
Copyright 2011 (C) Takeshi Horinouchi and GFD Dennou Club
(http://www.gfd-dennou.org/) All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY GFD DENNOU CLUB AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GFD DENNOU CLUB OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation
are those of the authors and should not be interpreted as representing
official policies, either expressed or implied, of Takeshi Horinouchi
and GFD Dennou Club.
ruby-numru-misc-0.1.1/doc/ 0000775 0000000 0000000 00000000000 12272751743 0015346 5 ustar 00root root 0000000 0000000 ruby-numru-misc-0.1.1/doc/emath.html 0000664 0000000 0000000 00000002135 12272751743 0017333 0 ustar 00root root 0000000 0000000
lib/numru/misc/emath.rb
To be included instead of the Math predefined module (or NMath in NArray).
Unlike Math and NMath, EMath handles unknown classes by calling its
native instance method (assuming the same name).
Therefore, if included, its function (module method) is used as:
cos( obj )
and so on. If obj is not of a supported class, EMath calls, obj.cos in
this case. (If cos is not a method of obj, then an exception is
raised.) Supported classes are Numeric (by Math) and NArray (by
NMath). EMath stands for "good Math" (for obvious reason for a
Japanese).
Note: as for atan2(a,b), a.atan2(b) will be called if a or b
is not supported. This is the case for all functions that take
two or more arguments.
ruby-numru-misc-0.1.1/doc/index.html 0000664 0000000 0000000 00000006630 12272751743 0017350 0 ustar 00root root 0000000 0000000
lib/numru/misc/misc.rb
Miscellaneous functions and classes to facilitate programming.
CLASSES
MODULES
- module MD_Iterators A Mixin for classes with
multi-dimension indexing support (such as NArray).
- module EMath
To be included instead of the Math predefined module (or NMath in NArray).
Unlike Math and NMath, EMath handles unknown classes by calling its
native instance method (assuming the same name).
MODULE FUNCTIONS
check_shape_consistency(cshapes, *args)
-
Check the consistency of array shapes (multi-dim such as NArray).
Exception is raised if inconsistent.
ARGUMENTS
- cshapes (String) : description of the shapes of the args.
Delimited by one-or-more spaces between arrays,
and the shape of each array is delimited by a comma. The lengths are
expressed with string names as identifiers (in that case, length
values are unquestioned) or specified as positive integers.
Use '..' or '...' for repetition of the last shape.
See EXAMPLES below.
- args (multi-dim arrays such as NArray): arrays to be checked
RETURN VALUE
POSSIBLE EXCEPTIONS
- exception is raised if cshapes and args are inconsistent:
- RuntimeError, if the arrays do not have shapes specified by cshapes.
- ArgeumentError, if the number of args are inconsistent with cshapes.
This is likely a coding error of the user.
EXAMPLES
to check whether three arrays u, v, and w are shaped as
u[nx], v[ny], and w[nx,ny], where nx and ny are any integer:
NumRu::Misc.check_shape_consistency('nx ny nx,ny',u,v,w)
Or equivalently,
NumRu::Misc.check_shape_consistency('m n m,n',u,v,w)
because actual strings does not matter.
To specify fixed lengths, use integers instead of names:
NumRu::Misc.check_shape_consistency('4 n 4,n',u,v,w)
In this case, u,v,w must have shapes [4], [ny], and [4,ny],
where ny is any length.
Use '..' or '...' to repeat the same shape:
NumRu::Misc.check_shape_consistency('nx,ny ...',u,v,w)
This ensures that u, v, and w are 2D arrays with the same shape.
Note: '..' and '...' are the same, so you can use whichever you like.
ruby-numru-misc-0.1.1/doc/keywordopt.html 0000664 0000000 0000000 00000016500 12272751743 0020445 0 ustar 00root root 0000000 0000000
lib/numru/misc/keywordopt.rb
A class to facilitate optional keyword arguments. More specifically,
it helps the use of a Hash to mimic the keyword argument system.
With this, you can set default values and description to each
keyword argument.
This is for your convenience. See the usage example below.
Suppose that you introduce keyword arguments "flag" and "number"
to the method "hoge" in a class/module Foo. It can be done as
follows:
require 'numru/misc' # or, specifically, require 'numru/misc/keywordopt'
include NumRu
class Foo
@@opt_hoge = Misc::KeywordOpt.new(
['flag', false, 'whether or not ...'],
['number', 1, 'number of ...'],
['help', false, 'show help message']
)
def hoge(regular_arg1, regular_arg2, options=nil)
opt = @@opt_hoge.interpret(options)
if opt['help']
puts @@opt_hoge.help
puts ' Current values='+opt.inspect
raise Misc::HelpMessagingException, '** show help message and raise **'
end
# do what you want below
# (options are set in the Hash opt: opt['flag'] and opt['number'])
end
end
Here, the options are defined in the class variable @@opt_hoge
with option names, default values, and descriptions (for help
messaging). One can use the method hoge as follows:
foo = Foo.new
...
x = ...
y = ...
...
foo.hoge( x, y, {'flag'=>true, 'number'=>10} )
Or equivalently,
foo.hoge( x, y, 'flag'=>true, 'number'=>10 )
because '{}' can be omitted here.
Tails of options names can be shortened as long as unambiguous:
foo.hoge( x, y, 'fla'=>true, 'num'=>10 )
To show the help message, call
foo.hoge( x, y, 'help'=>true )
This will cause the following help message printed with the
exception HelpMessagingException raised.
<< Description of options >>
option name => default value description:
"flag" => false whether or not ...
"number" => 1 number of ...
"help" => false show help message
Current values={"help"=>true, "number"=>1, "flag"=>false}
NumRu::Misc::HelpMessagingException: ** help messaging done **
from (irb):78:in "hoge"
from (irb):83
Do not affraid to write long descriptions. The help method
breaks lines nicely if they are long.
KeywordOpt.new( *args )
-
Constructor.
ARGUMENTS
args : (case 1) arrays of two or three elements: [option name,
default value, description ], or [option name, default value]
if you do not want to write descriptions. Option names and
descriptions must be String. (case 2) another KeywordOpt.
Cases 1 and 2 can be mixed.
When case 2, a link to the other KeywordOpt is kept. Thus, change
of values in it is reflected to the current one. However,
the link is deleted if values are changed by set.
RETURN VALUE
EXAMPLE
opt = Misc::KeywordOpt.new(
['flag', false, 'whether or not ...'],
['help', false, 'show help message']
)
opt = Misc::KeywordOpt.new(
['flag', false, 'whether or not ...'],
optA
)
interpret(hash)
-
Interprets a hash that specifies option values.
ARGUMENTS
- hash (Hash or nil) : a hash with string keys matching option names
(initializedwhen constructed). The matching is case sensitive and done
such that the tail of a option name can be omitted as long as
unambiguous (for example, 'num' for 'number').
If the argument is nil, the current values are returned.
If there are two options like 'max' and 'maxval', to use
a key 'max' (identical to the former paramer) is allowed, although
it matches 'maxval' as well. (Again 'ma' is regarded ambiguous.)
RETURN VALUE
- a Hash containing the option values (default values overwritten
with hash).
POSSIBLE EXCEPTION
- hash has a key that does not match any of the option names.
- hash has a key that is ambiguous
set(hash)
-
Similar to interpret but changes internal values.
ARGUMENTS
- hash (Hash) : see interpret. (Here, nil is not permitted though)
RETURN VALUE
- a Hash containing the values replaced (the ones before calling this
method)
POSSIBLE EXCEPTION
- the argument is not a Hash
- others are same as in interpret
help
-
Returns a help message
RETURN VALUE
- a String describing the option names, default values, and descriptions
[key]
-
Returns a value associated with the key (exact matching unlike interpret)
Same as class NumRu::Misc::KeywordOpt, but the method interpret
shows a help message and raise an exception if option 'help' is provided
as an argument and is not nil or false
(NumRu::Misc::HelpMessagingException < StandardError
)
or if the arguments cannot be interpreted correctly (ArgumentError
).
Option 'help' is automatically defined, so you do not have to define it
yourself.
ruby-numru-misc-0.1.1/doc/md_iterators.html 0000664 0000000 0000000 00000006215 12272751743 0020734 0 ustar 00root root 0000000 0000000
lib/numru/misc/md_iterators.rb
A Mixin.
To be included in a class with multi-dimension indexing support
(such as NArray).
each_subary_at_dims( *dims )
-
Iterator for each sub-array (not each element) specified by dimensions.
ARGUMENT
- dims (integers) : specifies subsets at dimensions
specified here with the beginning-to-end selection.
For example, [0, 1] to specify the first 2 dimensions
(subsets will be 2D then), and [2] to specify the 3rd
dimension (subsets will be 1D). Duplication has no effect,
so [0,0] and [0] are the same. Also, its order has no effect.
See EXAMPLE below for more.
RETURN VALUE
POSSIBLE EXCEPTIONS
- exception is raised if ( dims.min<0 || dims.max>=self.rank ).
EXAMPLE
Suppose that you want to do something with 2D sub-arrays in a
multi-dimension NArray. First, you include this module as follows:
require "narray"
class NArray
include NumRu::Misc::MD_Iterators
end
And prepare the array if you have not (here, it is 4D):
na = NArray.int(10,2,5,2).indgen!
Then you do the job like this:
na.each_subary_at_dims(0,2){ |sub|
... # do whatever with sub
}
This is equivalent to the following:
(0...na.shape[3]).each{|j|
(0...na.shape[1]).each{|i|
sub = na[0..-1, i, 0..-1, j]
... # do whatever with sub
}
}
Note that the loop must be nested 3 times when na is a 5D array,
if the latter approach is used. On the other hand, it will still
require the same single loop with the former.
each_subary_at_dims_with_index( *dims )
-
Like each_subary_at_dims but the block takes two arguments:
subset and the subset specifier (index).
EXAMPLE
Suppose the example above in each_subary_at_dims (EXAMPLE).
And suppose that you want to overwrite na with the result
you get. You can do it like this:
na.each_subary_at_dims_with_index(0,2){ |sub,idx|
result = (sub + 10) / 2
na[*idx] = result
}
Here, idx is an Array to be fed in the []= or [] methods
with asterisk (ungrouping).
ruby-numru-misc-0.1.1/doc/misc.html 0000664 0000000 0000000 00000006630 12272751743 0017174 0 ustar 00root root 0000000 0000000
lib/numru/misc/misc.rb
Miscellaneous functions and classes to facilitate programming.
CLASSES
MODULES
- module MD_Iterators A Mixin for classes with
multi-dimension indexing support (such as NArray).
- module EMath
To be included instead of the Math predefined module (or NMath in NArray).
Unlike Math and NMath, EMath handles unknown classes by calling its
native instance method (assuming the same name).
MODULE FUNCTIONS
check_shape_consistency(cshapes, *args)
-
Check the consistency of array shapes (multi-dim such as NArray).
Exception is raised if inconsistent.
ARGUMENTS
- cshapes (String) : description of the shapes of the args.
Delimited by one-or-more spaces between arrays,
and the shape of each array is delimited by a comma. The lengths are
expressed with string names as identifiers (in that case, length
values are unquestioned) or specified as positive integers.
Use '..' or '...' for repetition of the last shape.
See EXAMPLES below.
- args (multi-dim arrays such as NArray): arrays to be checked
RETURN VALUE
POSSIBLE EXCEPTIONS
- exception is raised if cshapes and args are inconsistent:
- RuntimeError, if the arrays do not have shapes specified by cshapes.
- ArgeumentError, if the number of args are inconsistent with cshapes.
This is likely a coding error of the user.
EXAMPLES
to check whether three arrays u, v, and w are shaped as
u[nx], v[ny], and w[nx,ny], where nx and ny are any integer:
NumRu::Misc.check_shape_consistency('nx ny nx,ny',u,v,w)
Or equivalently,
NumRu::Misc.check_shape_consistency('m n m,n',u,v,w)
because actual strings does not matter.
To specify fixed lengths, use integers instead of names:
NumRu::Misc.check_shape_consistency('4 n 4,n',u,v,w)
In this case, u,v,w must have shapes [4], [ny], and [4,ny],
where ny is any length.
Use '..' or '...' to repeat the same shape:
NumRu::Misc.check_shape_consistency('nx,ny ...',u,v,w)
This ensures that u, v, and w are 2D arrays with the same shape.
Note: '..' and '...' are the same, so you can use whichever you like.
ruby-numru-misc-0.1.1/install.rb 0000664 0000000 0000000 00000004350 12272751743 0016576 0 ustar 00root root 0000000 0000000 require 'rbconfig'
require 'find'
include Config
if CONFIG["MINOR"].to_i > 6 then $rb_18 = true else $rb_18 = false end
if $rb_18
require 'fileutils'
else
require 'ftools'
end
=begin
$version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
$libdir = File.join(CONFIG["libdir"], "ruby", $version)
# $archdir = File.join($libdir, CONFIG["arch"])
$site_libdir = $:.find {|x| x =~ /site_ruby$/}
if !$site_libdir
$site_libdir = File.join($libdir, "site_ruby")
elsif Regexp.compile($site_libdir) !~ Regexp.quote($version)
$site_libdir = File.join($site_libdir, $version)
end
default_destdir = $site_libdir
=end
default_destdir = CONFIG["sitelibdir"]
def install_rb(srcdir, destdir)
libdir = "lib"
libdir = File.join(srcdir, libdir) if srcdir
path = []
dir = []
Find.find(libdir) do |f|
next unless FileTest.file?(f)
next if (f = f[libdir.length+1..-1]) == nil
next if (/CVS$/ =~ File.dirname(f))
path.push f
dir |= [File.dirname(f)]
end
for f in dir
next if f == "."
next if f == "CVS"
if $rb_18
FileUtils.makedirs(File.join(destdir, f))
else
File::makedirs(File.join(destdir, f))
end
end
for f in path
next if (/\~$/ =~ f)
next if (/^\./ =~ File.basename(f))
if $rb_18
FileUtils.install(File.join("lib", f), File.join(destdir, f), {:mode => 0644, :verbose => true})
else
File::install(File.join("lib", f), File.join(destdir, f), 0644, true)
end
end
end
def ARGV.switch
return nil if self.empty?
arg = self.shift
return nil if arg == '--'
if arg =~ /^-(.)(.*)/
return arg if $1 == '-'
raise 'unknown switch "-"' if $2.index('-')
self.unshift "-#{$2}" if $2.size > 0
"-#{$1}"
else
self.unshift arg
nil
end
end
def ARGV.req_arg
self.shift || raise('missing argument')
end
destdir = default_destdir
begin
while switch = ARGV.switch
case switch
when '-d', '--destdir'
destdir = ARGV.req_arg
# when '-u', '--uninstall'
# uninstall = true
else
raise "unknown switch #{switch.dump}"
end
end
rescue
STDERR.puts $!.to_s
STDERR.puts File.basename($0) +
" -d "
exit 1
end
#if( defined?(uninstall) && uninstall )
# uninstall_rb(nil, destdir)
#else
install_rb(nil, destdir)
#end
ruby-numru-misc-0.1.1/lib/ 0000775 0000000 0000000 00000000000 12272751743 0015347 5 ustar 00root root 0000000 0000000 ruby-numru-misc-0.1.1/lib/numru/ 0000775 0000000 0000000 00000000000 12272751743 0016515 5 ustar 00root root 0000000 0000000 ruby-numru-misc-0.1.1/lib/numru/misc.rb 0000664 0000000 0000000 00000000167 12272751743 0020001 0 ustar 00root root 0000000 0000000 require 'numru/misc/misc'
require 'numru/misc/keywordopt'
require 'numru/misc/md_iterators'
require 'numru/misc/emath'
ruby-numru-misc-0.1.1/lib/numru/misc/ 0000775 0000000 0000000 00000000000 12272751743 0017450 5 ustar 00root root 0000000 0000000 ruby-numru-misc-0.1.1/lib/numru/misc/emath.rb 0000664 0000000 0000000 00000003507 12272751743 0021100 0 ustar 00root root 0000000 0000000 =begin
=module NumRu::Misc::EMath
To be included instead of the Math predefined module (or NMath in NArray).
Unlike Math and NMath, EMath handles unknown classes by calling its
native instance method (assuming the same name).
Therefore, if included, its function (module method) is used as:
cos( obj )
and so on. If obj is not of a supported class, EMath calls, obj.cos in
this case. (If cos is not a method of obj, then an exception is
raised.) Supported classes are Numeric (by Math) and NArray (by
NMath). EMath stands for "good Math" (for obvious reason for a
Japanese).
Note: as for atan2(a,b), a.atan2(b) will be called if a or b
is not supported. This is the case for all functions that take
two or more arguments.
=end
require "narray"
module NumRu
module Misc
module EMath
E = Math::E
PI = Math::PI
funcs = ["acos", "acosh", "asin", "asinh", "atan", "atan2", "atanh",
"cos", "cosh", "erf", "erfc", "exp", "frexp", "hypot",
"ldexp", "log", "log10", "sin", "sinh", "sqrt", "tan", "tanh"]
# FUNCS: from ruby 1.8.0, ( Math.methods - Object.methods ).sort
module_function
funcs.each{|func|
eval <<-EOS,nil,__FILE__,__LINE__+1
def #{func}(*arg)
case arg[0]
when Numeric
Math.#{func}(*arg)
when NArray
NMath.#{func}(*arg)
else
obj = arg.shift
begin
obj.#{func}(*arg)
rescue NameError
raise TypeError,"cannot handle \#{obj.class}: \#{obj.inspect}"
end
end
end
EOS
}
end
end
end
if __FILE__ == $0
include NumRu::Misc::EMath
p cos( PI )
p cos( Complex(0, 1) )
p cos( NArray[0,PI/3,PI/2] )
begin
p cos( "ggg" )
rescue
print "* error as expected >>: ",$!,"\n"
end
require 'narray_miss'
nam = NArrayMiss.to_nam( NArray[0,PI/3,PI/2] )
p cos(nam)
end
ruby-numru-misc-0.1.1/lib/numru/misc/keywordopt.rb 0000664 0000000 0000000 00000030316 12272751743 0022207 0 ustar 00root root 0000000 0000000 =begin
==Index
* (())
* (())
= class NumRu::Misc::KeywordOpt
== Overview
A class to facilitate optional keyword arguments. More specifically,
it helps the use of a Hash to mimic the keyword argument system.
With this, you can set default values and description to each
keyword argument.
== Classes defined supplementarilly
=== class NumRu::Misc::HelpMessagingException < StandardError
This is for your convenience. See the usage example below.
== Usage example
Suppose that you introduce keyword arguments "flag" and "number"
to the method "hoge" in a class/module Foo. It can be done as
follows:
require 'numru/misc' # or, specifically, require 'numru/misc/keywordopt'
include NumRu
class Foo
@@opt_hoge = Misc::KeywordOpt.new(
['flag', false, 'whether or not ...'],
['number', 1, 'number of ...'],
['help', false, 'show help message']
)
def hoge(regular_arg1, regular_arg2, options=nil)
opt = @@opt_hoge.interpret(options)
if opt['help']
puts @@opt_hoge.help
puts ' Current values='+opt.inspect
raise Misc::HelpMessagingException, '** show help message and raise **'
end
# do what you want below
# (options are set in the Hash opt: opt['flag'] and opt['number'])
end
end
Here, the options are defined in the class variable @@opt_hoge
with option names, default values, and descriptions (for help
messaging). One can use the method hoge as follows:
foo = Foo.new
...
x = ...
y = ...
...
foo.hoge( x, y, {'flag'=>true, 'number'=>10} )
Or equivalently,
foo.hoge( x, y, 'flag'=>true, 'number'=>10 )
because '{}' can be omitted here.
Tails of options names can be shortened as long as unambiguous:
foo.hoge( x, y, 'fla'=>true, 'num'=>10 )
To show the help message, call
foo.hoge( x, y, 'help'=>true )
This will cause the following help message printed with the
exception HelpMessagingException raised.
<< Description of options >>
option name => default value description:
"flag" => false whether or not ...
"number" => 1 number of ...
"help" => false show help message
Current values={"help"=>true, "number"=>1, "flag"=>false}
NumRu::Misc::HelpMessagingException: ** help messaging done **
from (irb):78:in "hoge"
from (irb):83
Do not affraid to write long descriptions. The help method
breaks lines nicely if they are long.
== Class methods
---KeywordOpt.new( *args )
Constructor.
ARGUMENTS
* args : (case 1) arrays of two or three elements: [option name,
default value, description ], or [option name, default value]
if you do not want to write descriptions. Option names and
descriptions must be String. (case 2) another KeywordOpt.
Cases 1 and 2 can be mixed.
When case 2, a link to the other KeywordOpt is kept. Thus, change
of values in it is reflected to the current one. However,
the link is deleted if values are changed by (()).
RETURN VALUE
* a KeywordOpt object
EXAMPLE
* case 1
opt = Misc::KeywordOpt.new(
['flag', false, 'whether or not ...'],
['help', false, 'show help message']
)
* case 2
opt = Misc::KeywordOpt.new( optA, optB )
* case 1 & 2
opt = Misc::KeywordOpt.new(
['flag', false, 'whether or not ...'],
optA
)
== Methods
---interpret(hash)
Interprets a hash that specifies option values.
ARGUMENTS
* hash (Hash or nil) : a hash with string keys matching option names
(initializedwhen constructed). The matching is case sensitive and done
such that the tail of a option name can be omitted as long as
unambiguous (for example, 'num' for 'number').
If the argument is nil, the current values are returned.
If there are two options like 'max' and 'maxval', to use
a key 'max' (identical to the former paramer) is allowed, although
it matches 'maxval' as well. (Again 'ma' is regarded ambiguous.)
RETURN VALUE
* a Hash containing the option values (default values overwritten
with hash).
POSSIBLE EXCEPTION
* hash has a key that does not match any of the option names.
* hash has a key that is ambiguous
---set(hash)
Similar to (()) but changes internal values.
ARGUMENTS
* hash (Hash) : see (()). (Here, nil is not permitted though)
RETURN VALUE
* a Hash containing the values replaced (the ones before calling this
method)
POSSIBLE EXCEPTION
* the argument is not a Hash
* others are same as in (())
---help
Returns a help message
RETURN VALUE
* a String describing the option names, default values, and descriptions
---[](key)
Returns a value associated with the key (exact matching unlike interpret)
---keys
Retunrs the keys.
---select_existent(hash_or_keys)
Copies hash_or_keys, exclude ones that are not included in the option
(by comparing keys), and returns it. I.e. select only the ones
exsitent.
NOTE: ambiguity is not checked, so the resultant value is not
necessarily accepted by (()).
ARGUMENTS
* hash_or_keys (Hash or Array)
RETURN VALUE
* a Hash or Array depending on the class of the argument hash_or_keys
= class NumRu::Misc::KeywordOptAutoHelp < NumRu::Misc::KeywordOpt
Same as (()), but the method (())
shows a help message and raise an exception if option 'help' is provided
as an argument and is not nil or false
((({NumRu::Misc::HelpMessagingException < StandardError})))
or if the arguments cannot be interpreted correctly ((({ArgumentError}))).
Option 'help' is automatically defined, so you do not have to define it
yourself.
=end
module NumRu
module Misc
class HelpMessagingException < StandardError
end
class KeywordOpt
def initialize(*args)
# USAGE:
# KeywordOpt.new([key,val,description],[key,val,description],..)
# where key is a String, and description can be omitted.
@val=Hash.new
@description=Hash.new
@keys = []
args.each{ |x|
case x
when Array
unless (x[0]=='help') && @keys.include?(x[0])
#^only 'help' can overwrap in the arguments
@keys.push(x[0])
@val[x[0]] = x[1]
@description[x[0]] = ( (x.length>=3) ? x[2] : '' )
end
when KeywordOpt
x.keys.each{|k|
unless k=='help' && @keys.include?(k)
#^only 'help' can overwrap in the arguments
@keys.push(k)
@val[k] = x #.val[k]
@description[k] = x.description[k]
end
}
def @val.[](k)
val = super(k)
val.is_a?(KeywordOpt) ? val[k] : val
end
def @val.dup
out = Hash.new
each{|k,val| out[k] = (val.is_a?(KeywordOpt) ? val[k] : val)}
out
end
else
raise ArgumentError, "invalid argument: #{x.inspect}"
end
}
@keys_sort = @keys.sort
if @keys_sort.length != @keys_sort.uniq.length
raise ArgumentError, "keys are not unique"
end
end
def interpret(hash)
return @val.dup if hash.nil?
##
len = @val.length
im = 0
out = @val.dup
hash.keys.sort.each do |key|
rkey = /^#{key}/
loop do
if rkey =~ @keys_sort[im]
if im= 68
# idx = str[0..67].rindex(/\s/)
# if idx
# str[idx, 1] = "\n\t"
# end
# end
# str
# end
def __line_feed(str, len)
if str.length >= len
idx = str[0...len].rindex(/\s/)
if idx
str = str[0...idx] + "\n\t\t\t# " + __line_feed(str[(idx+1)..-1],50)
end
end
str
end
private :__line_feed
def help
" option name\tdefault value\t# description:\n" +
@keys.collect{|k|
__line_feed(" #{k.inspect}\t#{@val[k].inspect}\t# #{@description[k]}", 66)
}.join("\n")
end
def [](k)
v = @val[k]
if v.is_a?(KeywordOpt)
v = v.val[k]
end
v
end
def keys
@keys.dup
end
##### protected methods #####
protected
attr_reader :val, :description
end
##################################################
class KeywordOptAutoHelp < KeywordOpt
def initialize(*args)
args.push(['help', false, 'show help message if true'])
super(*args)
end
def interpret(hash)
begin
out = super(hash)
rescue
raise $!.inspect + "\n Available parameters are:\n" + help
end
if out['help']
puts "<< Description of options >>\n" + help
puts ' Current values=' + out.inspect
raise Misc::HelpMessagingException, '** help messaging done **'
end
out
end
def set(hash)
raise ArgumentError, "not a hash" if !hash.is_a?(Hash)
if hash['help']
puts "<< Description of options >>\n" + help
raise Misc::HelpMessagingException, '** help messaging done **'
end
super
end
end
end
end
if __FILE__ == $0
include NumRu
class Foo
@@opt_hoge = Misc::KeywordOpt.new(
['flag', false, 'whether or not ...'],
['number', 1, 'number of ...'],
['fff', 1, 'fff...'],
['help', false, 'show help message']
)
def self.change_default(hash)
@@opt_hoge.set(hash)
end
def hoge(regular_arg1, regular_arg2, options=nil)
opt = @@opt_hoge.interpret(options)
if opt['help']
puts "* Description of options:\n" + @@opt_hoge.help
puts ' Current values='+opt.inspect
raise Misc::HelpMessagingException, '** show help message and raise **'
end
# do what you want below
# (options are set in the Hash opt: opt['flag'] and opt['number'])
p opt
end
end
foo = Foo.new
x = 1
y = 1
print "### 0 ###\n"
foo.hoge( x, y, {'flag'=>true, 'number'=>10} )
foo.hoge( x, y )
print "### 1 ###\n"
foo.hoge( x, y, 'fla'=>true, 'num'=>10 )
print "### 2 ###\n"
begin
foo.hoge( x, y, 'help'=>true )
rescue
puts $!
end
print "### 3 ###\n"
Foo.change_default( {'number'=>3} )
begin
foo.hoge( x, y, 'fla'=>true, 'num'=>10, 'help'=>true)
rescue
puts $!
end
print "### 4 ###\n"
begin
foo.hoge( x, y, 'dummy'=>nil)
rescue
puts $!
end
print "### 5 ###\n"
begin
foo.hoge( x, y, 'f'=>nil)
rescue
puts $!
end
print "\n###### test of KeywordOptAutoHelp ######\n"
opt = Misc::KeywordOptAutoHelp.new(
['flag', false, 'whether or not ...'],
['number', 1, 'number of ...']
)
print "### 11 ###\n"
begin
opt.interpret('flag'=>10,'help'=>true)
rescue
puts $!
end
print "### 12 ###\n"
begin
opt.interpret('nnn'=>10)
rescue
puts $!
end
print "### 13 ###\n"
opt2 = Misc::KeywordOptAutoHelp.new(
['flafla', false, 'whether or not ...']
)
opt3 = Misc::KeywordOptAutoHelp.new( opt, opt2 )
p opt3.interpret('flag'=>true)
begin
opt3.interpret('help'=>true)
rescue
puts $!
end
print "### 14 ###\n"
p opt2.keys, opt.keys
p opt.select_existent({"flag"=>99, "num"=>88, 'acb'=>333})
p opt.select_existent(["flag", "num", 'acb'])
end
ruby-numru-misc-0.1.1/lib/numru/misc/md_iterators.rb 0000664 0000000 0000000 00000010262 12272751743 0022472 0 ustar 00root root 0000000 0000000 =begin
=module NumRu::Misc::MD_Iterators
A Mixin.
To be included in a class with multi-dimension indexing support
(such as NArray).
==Index
* (())
* (())
==Methods
---each_subary_at_dims( *dims )
Iterator for each sub-array (not each element) specified by dimensions.
ARGUMENT
* ((|dims|)) (integers) : specifies subsets at dimensions
specified here with the beginning-to-end selection.
For example, [0, 1] to specify the first 2 dimensions
(subsets will be 2D then), and [2] to specify the 3rd
dimension (subsets will be 1D). Duplication has no effect,
so [0,0] and [0] are the same. Also, its order has no effect.
See EXAMPLE below for more.
RETURN VALUE
* self
POSSIBLE EXCEPTIONS
* exception is raised if ( dims.min<0 || dims.max>=self.rank ).
EXAMPLE
* Suppose that you want to do something with 2D sub-arrays in a
multi-dimension NArray. First, you include this module as follows:
require "narray"
class NArray
include NumRu::Misc::MD_Iterators
end
And prepare the array if you have not (here, it is 4D):
na = NArray.int(10,2,5,2).indgen!
Then you do the job like this:
na.each_subary_at_dims(0,2){ |sub|
... # do whatever with sub
}
This is equivalent to the following:
(0...na.shape[3]).each{|j|
(0...na.shape[1]).each{|i|
sub = na[0..-1, i, 0..-1, j]
... # do whatever with sub
}
}
Note that the loop must be nested 3 times when (('na')) is a 5D array,
if the latter approach is used. On the other hand, it will still
require the same single loop with the former.
---each_subary_at_dims_with_index( *dims )
Like (()) but the block takes two arguments:
subset and the subset specifier (index).
EXAMPLE
* Suppose the example above in (()) (EXAMPLE).
And suppose that you want to overwrite (('na')) with the result
you get. You can do it like this:
na.each_subary_at_dims_with_index(0,2){ |sub,idx|
result = (sub + 10) / 2
na[*idx] = result
}
Here, (('idx')) is an Array to be fed in the []= or [] methods
with asterisk (ungrouping).
=end
module NumRu
module Misc
module MD_Iterators
def each_subary_at_dims( *dims )
if dims.min<0 || dims.max>=rank
raise ArguemntError,"Invalid dims #{dims.inspect} for #{rank}D array"
end
loopdims = Array.new
sh = Array.new
len = 1
(0...rank).each{|i|
if !dims.include?(i)
loopdims.push(i)
sh.push(shape[i])
len *= shape[i]
end
}
if loopdims.length == 0
yield(self)
return self
end
cs = [1]
(1...sh.length).each{|i| cs[i] = sh[i-1]*cs[i-1]}
idx = Array.new
all = 0..-1
for i in 0...len do
loopdims.each_with_index{|d,j| idx[d] = ( (i/cs[j])%sh[j] )}
dims.each{|d| idx[d] = all}
sub = self[ *idx ]
yield(sub)
end
self
end
def each_subary_at_dims_with_index( *dims )
if dims.min<0 || dims.max>=rank
raise ArguemntError,"Invalid dims #{dims.inspect} for #{rank}D array"
end
loopdims = Array.new
sh = Array.new
len = 1
(0...rank).each{|i|
if !dims.include?(i)
loopdims.push(i)
sh.push(shape[i])
len *= shape[i]
end
}
if loopdims.length == 0
yield(self, false)
return self
end
cs = [1]
(1...sh.length).each{|i| cs[i] = sh[i-1]*cs[i-1]}
idx = Array.new
all = 0..-1
for i in 0...len do
loopdims.each_with_index{|d,j| idx[d] = ( (i/cs[j])%sh[j] )}
dims.each{|d| idx[d] = all}
sub = self[ *idx ]
yield(sub, idx)
end
self
end
end
end
end
##################################
if __FILE__ == $0
require "narray"
class NArray
include NumRu::Misc::MD_Iterators
end
na = NArray.int(10,2,2,2).indgen!
puts "** test A **"
na.each_subary_at_dims(0,1){ |sub|
p sub
}
puts "** test B **"
na.each_subary_at_dims(0,3){ |sub|
p sub
}
puts "** test C **"
na.each_subary_at_dims(2,1,0){ |sub| # same as (0,1,2)
p sub
}
puts "** test C **"
na.each_subary_at_dims(0,1,2,3){ |sub|
p sub
}
end
ruby-numru-misc-0.1.1/lib/numru/misc/misc.rb 0000664 0000000 0000000 00000012457 12272751743 0020741 0 ustar 00root root 0000000 0000000 =begin
= module NumRu::Misc
== Overview
Miscellaneous functions and classes to facilitate programming.
== Index
CLASSES
* (())
to support keyward arguments with default values.
* (())
MODULES
* (()) A Mixin for classes with
multi-dimension indexing support (such as NArray).
* (())
To be included instead of the Math predefined module (or NMath in NArray).
Unlike Math and NMath, EMath handles unknown classes by calling its
native instance method (assuming the same name).
MODULE FUNCTIONS
* (())
== Module functions
---check_shape_consistency(cshapes, *args)
Check the consistency of array shapes (multi-dim such as NArray).
Exception is raised if inconsistent.
ARGUMENTS
* cshapes (String) : description of the shapes of the args.
Delimited by one-or-more spaces between arrays,
and the shape of each array is delimited by a comma. The lengths are
expressed with string names as identifiers (in that case, length
values are unquestioned) or specified as positive integers.
Use '..' or '...' for repetition of the last shape.
See EXAMPLES below.
* args (multi-dim arrays such as NArray): arrays to be checked
RETURN VALUE
* nil
POSSIBLE EXCEPTIONS
* exception is raised if cshapes and args are inconsistent:
* RuntimeError, if the arrays do not have shapes specified by cshapes.
* ArgeumentError, if the number of args are inconsistent with cshapes.
This is likely a coding error of the user.
EXAMPLES
* to check whether three arrays u, v, and w are shaped as
u[nx], v[ny], and w[nx,ny], where nx and ny are any integer:
NumRu::Misc.check_shape_consistency('nx ny nx,ny',u,v,w)
Or equivalently,
NumRu::Misc.check_shape_consistency('m n m,n',u,v,w)
because actual strings does not matter.
* To specify fixed lengths, use integers instead of names:
NumRu::Misc.check_shape_consistency('4 n 4,n',u,v,w)
In this case, u,v,w must have shapes [4], [ny], and [4,ny],
where ny is any length.
* Use '..' or '...' to repeat the same shape:
NumRu::Misc.check_shape_consistency('nx,ny ...',u,v,w)
This ensures that u, v, and w are 2D arrays with the same shape.
Note: '..' and '...' are the same, so you can use whichever you like.
=end
require "narray"
module NumRu
module Misc
module_function
def check_shape_consistency(cshapes, *args)
ranks = Array.new
elm2idx = Hash.new
spl = cshapes.split(' +')
if spl.length >= 2 && /^\.\.\.?$/ =~ spl[-1] # '..' or '...'
((spl.length-1)...args.length).each{|i|
spl[i]=spl[i-1]
}
end
if spl.length != args.length
raise ArgumentError,"# of the argument (#{args.length}) is inconsistent with the 1st arg '#{cshapes}'"
end
spl.each_with_index{|csh,i|
sh = csh.split(',')
ranks.push( sh.length )
sh.each_with_index{|tag,j|
elm2idx[tag] = Array.new if !elm2idx[tag]
elm2idx[tag].push([i,j])
}
}
ranks.each_with_index{|len,i|
if args[i].rank != len
raise "(#{i+1}th arg) unexepected rank #{args[i].rank} for #{len}"
end
}
elm2idx.each{|tag,ary|
if tag.to_i > 0 # numeric (positive integer)
size = tag.to_i
start = 0
else # alphabet
size = args[ary[0][0]].shape[ary[0][1]]
start = 1
end
(start...ary.length).each{|i|
if args[ary[i][0]].shape[ary[i][1]] != size
if start == 0
raise "length of dim #{ary[i][1]} of #{ary[i][0]+1}th "+
"arg is unexpected " +
"(#{args[ary[i][0]].shape[ary[i][1]]} for #{size})"
else
raise "Dimension lengths inconsistent between "+
"dim #{ary[0][1]} of #{ary[0][0]+1}th arg and " +
"dim #{ary[i][1]} of #{ary[i][0]+1}th arg"
end
end
}
}
nil
end
end
end
if __FILE__ == $0
include NumRu
puts '* test A *'
u = NArray.float(3)
v = NArray.float(5)
w = NArray.float(3,5)
Misc.check_shape_consistency('nx ny nx,ny',u,v,w)
puts ' OK'
Misc.check_shape_consistency('3 ny 3,ny',u,v,w)
puts ' OK'
begin
Misc.check_shape_consistency('6 ny 6,ny',u,v,w)
rescue
puts " exception raised as expected\n"+$!
puts ' OK'
end
puts '* test B *'
Misc.check_shape_consistency('nx,ny ...',w,w,w,w)
puts ' OK'
puts '* test C *'
begin
u = NArray.float(4)
v = NArray.float(5)
w = NArray.float(3,5)
Misc.check_shape_consistency('nx ny nx,ny',u,v,w)
rescue
puts " exception raised as expected\n"+$!
puts ' OK'
end
puts '* test D *'
begin
u = NArray.float(3,5)
v = NArray.float(5)
w = NArray.float(3,5)
Misc.check_shape_consistency('nx ny nx,ny',u,v,w)
rescue
puts " exception raised as expected\n"+$!
puts ' OK'
end
puts '* test E *'
u = NArray.float(3,5,7)
v = NArray.float(5)
w = NArray.float(3,5)
1000.times{ Misc.check_shape_consistency('nx,ny,nz ny nx,ny',u,v,w) }
puts ' OK'
end
ruby-numru-misc-0.1.1/makedoc.csh 0000775 0000000 0000000 00000000376 12272751743 0016714 0 ustar 00root root 0000000 0000000 #!/bin/csh
rd2 lib/numru/misc/misc.rb >! doc/misc.html
\cp -pf doc/misc.html doc/index.html
rd2 lib/numru/misc/keywordopt.rb >! doc/keywordopt.html
rd2 lib/numru/misc/md_iterators.rb >! doc/md_iterators.html
rd2 lib/numru/misc/emath.rb >! doc/emath.html