datafarming 1.4.0 → 2.2.0
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.
- checksums.yaml +4 -4
- data/LICENSE.md +1 -1
- data/README.md +10 -6
- data/datafarming.gemspec +11 -6
- data/exe/datafarming.rb +33 -27
- data/exe/generate_design.rb +306 -0
- data/lib/datafarming/freq_sets.rb +52 -243
- data/lib/datafarming/nolh_designs.rb +19105 -4483
- data/lib/datafarming/res_v_seqs.rb +57 -0
- data/lib/datafarming/scale_design.rb +29 -0
- data/lib/datafarming/screen_freq_sets.rb +143 -0
- data/lib/datafarming/version.rb +5 -0
- data/lib/datafarming.rb +8 -0
- metadata +42 -18
- data/DESCRIPTIONS.html +0 -1107
- data/DESCRIPTIONS.md +0 -45
- data/exe/augment_design.rb +0 -66
- data/exe/scaled_fde.rb +0 -169
- data/exe/scaled_rf_cubed.rb +0 -173
- data/exe/stack_nolhs.rb +0 -174
- data/lib/datafarming/factorial_generator.rb +0 -49
data/DESCRIPTIONS.md
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
#### COMMAND-LINE TOOLS
|
2
|
-
|
3
|
-
Ruby is a powerful and concise object-oriented scripting language. Scripts are normally run from a command-line or terminal environment by typing the `ruby` command followed by a script name, often followed by one or more command-line arguments. However, scripts installed as gems do not need the `ruby` command to be typed explicitly. For example, typing `stripheaderdups.rb my_file.txt` will invoke the `stripheaderdups.rb` script and apply it to file `my_file.txt` in your current working directory. Note that on Windows the `.rb` suffix is not needed to run your scripts, e.g., `stripheaderdups my_file.txt` will suffice.
|
4
|
-
|
5
|
-
All scripts in this distribution are self documenting if run with a `--help`, `-h`, or `-?` option. Quick descriptions follow.
|
6
|
-
|
7
|
-
#### DATA MANIPULATION
|
8
|
-
- `blank2csv.rb` —
|
9
|
-
convert whitespace-delimited files to Comma Separated Values (CSV) files
|
10
|
-
- `cat.rb` —
|
11
|
-
Unix `cat` program work-alike for Windows—for viewing or creating text files or concatenating multiple files, based on stdio
|
12
|
-
- `convert_line_endings.rb` —
|
13
|
-
convert text files (including CSV files) to your current operating system environment (e.g., DOS to Unix or Unix to DOS)
|
14
|
-
- `csv2blank.rb` —
|
15
|
-
convert CSV files to whitespace-delimited files
|
16
|
-
- `pool_files.rb` —
|
17
|
-
pool columns from separate files into a new file, useful for combining design file & output files or multiple output files
|
18
|
-
- `stripheaders.rb`, `stripheaderdups.rb` —
|
19
|
-
remove column headers from a file, or duplicate headers within a file, respectively
|
20
|
-
|
21
|
-
#### DESIGN GENERATORS
|
22
|
-
- `augment_design.rb` —
|
23
|
-
generate star points to augment an already existing factorial design
|
24
|
-
- `cross.rb` —
|
25
|
-
create a combinatorial design by crossing all combinations of any # of individual smaller designs
|
26
|
-
- `scaled_fde.rb` —
|
27
|
-
generate fully orthogonal quadratic designs based on discrete Fourier frequencies, with factor scaling
|
28
|
-
- `scaled_rf_cubed.rb` —
|
29
|
-
generate 2-level Resolution V fractional factorial designs and Central Composite Designs (CCDs), with factor scaling
|
30
|
-
- `stack_nolhs.rb` —
|
31
|
-
generate designs by reassigning columns from pre-tabled NOLHs, with factor scaling, for up to 100 factors
|
32
|
-
|
33
|
-
#### RUN CONTROL
|
34
|
-
- `batchrunner.rb` —
|
35
|
-
run a model interactively with replication
|
36
|
-
- `rundesign_general.rb` —
|
37
|
-
run control to replicate a designed experiment applied to a model
|
38
|
-
|
39
|
-
#### CONFIDENCE INTERVALS FOR TIME SERIES
|
40
|
-
- `mser.rb` —
|
41
|
-
use MSER truncation to remove initial transient effects for time-series output, reporting truncated average and number of observations for each run to facilitate construction of a properly weighted confidence interval.
|
42
|
-
- `mser_nolbm.rb` —
|
43
|
-
use MSER truncation to remove initial transient effects for time-series output, then calculate a 95% confidence interval on the remaining data using non-overlapping batch means.
|
44
|
-
- `mser_olbm.rb` —
|
45
|
-
use MSER truncation to remove initial transient effects for time-series output, then calculate a 95% confidence interval on the remaining data using overlapping batch means.
|
data/exe/augment_design.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -w
|
2
|
-
|
3
|
-
# This script generates star points to augment a fractional factorial
|
4
|
-
# so you can check for quadratic effects.
|
5
|
-
|
6
|
-
require 'colorize'
|
7
|
-
|
8
|
-
String.disable_colorization false
|
9
|
-
|
10
|
-
require 'optparse'
|
11
|
-
require 'datafarming/error_handling'
|
12
|
-
|
13
|
-
help_msg = [
|
14
|
-
'Generate star points to augment a fractional factorial ' \
|
15
|
-
'with quadratic effects.',
|
16
|
-
'Results are white-space delimited data written to ' +
|
17
|
-
'stdout'.light_blue + ', and can be redirected', 'as desired.', '',
|
18
|
-
'Syntax:',
|
19
|
-
"\n\t#{ErrorHandling.prog_name} [--help] FACTOR_INFO".yellow, '',
|
20
|
-
"Arguments in square brackets are optional. A vertical bar '|'",
|
21
|
-
'indicates valid alternatives for invoking the option. Prefix',
|
22
|
-
'the command with "' + 'ruby'.yellow +
|
23
|
-
'" if it is not on your PATH.', '',
|
24
|
-
' --help | -h | -? | ?'.green,
|
25
|
-
"\tProduce this help message.",
|
26
|
-
' FACTOR_INFO'.green,
|
27
|
-
"\tEITHER the number of factors (produces standardized +/-1 design),",
|
28
|
-
"\tOR pairs of values " + 'low1 hi1 low2 hi2...lowN hiN'.green +
|
29
|
-
' for each of the',
|
30
|
-
"\tN factors.", ''
|
31
|
-
]
|
32
|
-
|
33
|
-
OptionParser.new do |opts|
|
34
|
-
opts.banner = "Usage: #{$PROGRAM_NAME} [-h|--help] [number of factors]"
|
35
|
-
opts.on('-h', '-?', '--help') { ErrorHandling.clean_abort help_msg }
|
36
|
-
end.parse!
|
37
|
-
|
38
|
-
if ARGV.length == 0 || (ARGV[0] == '?') || (ARGV.length > 1 && ARGV.length.odd?)
|
39
|
-
ErrorHandling.clean_abort help_msg
|
40
|
-
else
|
41
|
-
num_factors = 0
|
42
|
-
if ARGV.length == 1
|
43
|
-
num_factors = ARGV.shift.to_i
|
44
|
-
x = Array.new(num_factors, ' 0')
|
45
|
-
ranges = Array.new(2 * num_factors)
|
46
|
-
ranges.each_index { |i| ranges[i] = (i.even? ? '-1' : ' 1') }
|
47
|
-
else
|
48
|
-
num_factors = ARGV.length / 2
|
49
|
-
x = Array.new(num_factors)
|
50
|
-
ranges = ARGV
|
51
|
-
num_factors.times do |i|
|
52
|
-
x[i] = 0.5 * (ranges[2 * i].to_f + ranges[2 * i + 1].to_f)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
# create and print an array at the global center point (0,0,...,0)
|
56
|
-
puts x.join(' ')
|
57
|
-
|
58
|
-
# now generate and print the star points at +/-1 along each factor axis
|
59
|
-
num_factors.times do |i|
|
60
|
-
y = x.clone
|
61
|
-
y[i] = ranges[2 * i]
|
62
|
-
puts y.join(' ')
|
63
|
-
y[i] = ranges[2 * i + 1]
|
64
|
-
puts y.join(' ')
|
65
|
-
end
|
66
|
-
end
|
data/exe/scaled_fde.rb
DELETED
@@ -1,169 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -w
|
2
|
-
|
3
|
-
require 'colorize'
|
4
|
-
String.disable_colorization false
|
5
|
-
|
6
|
-
require 'datafarming/error_handling'
|
7
|
-
require 'datafarming/freq_sets'
|
8
|
-
|
9
|
-
help_msg = [
|
10
|
-
'Generate scaled FDE designs with shifting and stacking. The resulting',
|
11
|
-
'design is written to ' +
|
12
|
-
'stdout'.light_blue + '.', '',
|
13
|
-
'Syntax:',
|
14
|
-
"\n\t#{$PROGRAM_NAME.split(%r{/|\\})[-1]} [--help]".yellow +
|
15
|
-
" [-c] [-d #] [-e] [-k #] [-s #] [file_name]\n".yellow,
|
16
|
-
"Arguments in square brackets are optional. A vertical bar '|'",
|
17
|
-
'indicates valid alternatives for invoking the option. Prefix',
|
18
|
-
'the command with "' + 'ruby'.yellow +
|
19
|
-
'" if it is not on your PATH.', '',
|
20
|
-
' --help | -h | -? | ?'.green,
|
21
|
-
"\tProduce this help message. Supersedes any other choices.",
|
22
|
-
' --csv | -c'.green,
|
23
|
-
"\tGenerate output as comma-separated-values.",
|
24
|
-
' --num_factors # | -k #'.green,
|
25
|
-
"\tSpecify number of factors using standard (+/-1) scaling.",
|
26
|
-
' --design # | -d #'.green,
|
27
|
-
"\tSpecify which design number you want. Default is highest",
|
28
|
-
"\tfrequency set available for the target number of factors.",
|
29
|
-
"\tAn input larger than the available number will produce an",
|
30
|
-
"\terror message that identifies the allowable range.",
|
31
|
-
' --stack # | -s #'.green,
|
32
|
-
"\t# specifies the number of stackings. The specified value cannot",
|
33
|
-
"\texceed the number of columns in the design being used. If this",
|
34
|
-
"\toption is omitted then only the base design is generated.",
|
35
|
-
' --excel-style-input | -e'.green,
|
36
|
-
"\tSpecify factor ranges similarly to the NOLH spreadsheet, i.e.,",
|
37
|
-
"\tthe first line is the set of minimum range values for all factors,",
|
38
|
-
"\tand the second line is maximum range values. Without this option,",
|
39
|
-
"\tthe default input format is one line per factor, comprised of the",
|
40
|
-
"\tmin and max separated by commas or whitespace.",
|
41
|
-
' file_name'.green,
|
42
|
-
"\tThe name of a file containing the factor specifications. If no",
|
43
|
-
"\tfilename is given, the user can enter the values interactively in",
|
44
|
-
"\tthe desired form or use file redirection with '<'.", '',
|
45
|
-
'Options may be given in any order, but must come before the file name',
|
46
|
-
'if one is provided.'
|
47
|
-
]
|
48
|
-
|
49
|
-
# Scaler objects will rescale a FDE design from standard units
|
50
|
-
# to a range specified by min and max
|
51
|
-
class Scaler
|
52
|
-
def initialize(min = -1, max = 1)
|
53
|
-
@mid = 0.5 * (max + min)
|
54
|
-
@amplitude = 0.5 * (max - min)
|
55
|
-
end
|
56
|
-
|
57
|
-
def scale(value)
|
58
|
-
@mid + @amplitude * value
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def make_design(number_of_factors, design_num = -1)
|
63
|
-
design = Array.new(number_of_factors)
|
64
|
-
ds = FDE::DESIGN_SETS[number_of_factors]
|
65
|
-
freqs = ds.freqs[design_num].map { |f| Rational(f, ds.nyq) }
|
66
|
-
design.each_index do |column|
|
67
|
-
omega = freqs[column]
|
68
|
-
design[column] = Array.new(ds.nyq) do |i|
|
69
|
-
Math.sin(((i * omega) % 1) * FDE::TWO_PI)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
design.transpose
|
73
|
-
end
|
74
|
-
|
75
|
-
excel_style_inputs = false
|
76
|
-
csv_out = false
|
77
|
-
design_num = -1
|
78
|
-
num_stackings = 1
|
79
|
-
n = nil
|
80
|
-
while ARGV[0] && (ARGV[0][0] == '-' || ARGV[0][0] == 45 || ARGV[0][0] == '?')
|
81
|
-
current_value = ARGV.shift
|
82
|
-
case current_value
|
83
|
-
when '--csv', '-c'
|
84
|
-
csv_out = true
|
85
|
-
when '--design', '-d'
|
86
|
-
design_num = ARGV.shift.to_i - 1
|
87
|
-
when '--num_factors', '-k'
|
88
|
-
n = ARGV.shift.to_i
|
89
|
-
when '--stack', '-s'
|
90
|
-
num_stackings = ARGV.shift.to_i
|
91
|
-
when '--excel-style-input', '-e'
|
92
|
-
excel_style_inputs = true
|
93
|
-
when '--help', '-h', '-help', '-?', '?'
|
94
|
-
ErrorHandling.clean_abort help_msg
|
95
|
-
else
|
96
|
-
ErrorHandling.message ['Unknown argument: '.red + current_value.yellow]
|
97
|
-
ErrorHandling.clean_abort help_msg
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
if n
|
102
|
-
factor = Array.new(n) { Scaler.new }
|
103
|
-
else
|
104
|
-
begin
|
105
|
-
if excel_style_inputs
|
106
|
-
if ARGF.filename == '-'
|
107
|
-
STDERR.puts 'Enter one line of min values, and one of max values.'.green
|
108
|
-
end
|
109
|
-
min_values = ARGF.gets.strip.split(/\s*[,;:]\s*|\s+/).map(&:to_f)
|
110
|
-
max_values = ARGF.gets.strip.split(/\s*[,;:]\s*|\s+/).map(&:to_f)
|
111
|
-
else
|
112
|
-
if ARGF.filename == '-'
|
113
|
-
STDERR.puts 'To terminate input enter '.green + 'ctrl-d'.cyan +
|
114
|
-
' (Mac/Unix/Linux)'.green + ' or '.green + 'ctrl-z'.cyan +
|
115
|
-
' (Windows).'.green
|
116
|
-
STDERR.puts 'Enter ranges for each factor on a separate line.'.green
|
117
|
-
STDERR.puts "\nMIN\tMAX".cyan
|
118
|
-
end
|
119
|
-
min_values = []
|
120
|
-
max_values = []
|
121
|
-
while line = ARGF.gets
|
122
|
-
values = line.strip.split(/\s*[,;:]\s*|\s+/).map(&:to_f)
|
123
|
-
min_values << values.shift
|
124
|
-
max_values << values.shift
|
125
|
-
end
|
126
|
-
end
|
127
|
-
rescue StandardError => e
|
128
|
-
ErrorHandling.message [e.message.red]
|
129
|
-
ErrorHandling.clean_abort help_msg
|
130
|
-
end
|
131
|
-
|
132
|
-
n = min_values.size
|
133
|
-
if max_values.size != n
|
134
|
-
ErrorHandling.message ['Unequal counts for min, max'.red]
|
135
|
-
ErrorHandling.clean_abort help_msg
|
136
|
-
end
|
137
|
-
|
138
|
-
factor = Array.new(n) do |i|
|
139
|
-
Scaler.new(min_values[i], max_values[i])
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
if design_num >= FDE::DESIGN_SETS[n].freqs.length
|
144
|
-
ErrorHandling.clean_abort [
|
145
|
-
"Design number cannot exceed #{FDE::DESIGN_SETS[n].freqs.length} for #{n} factors".red
|
146
|
-
]
|
147
|
-
end
|
148
|
-
|
149
|
-
design = make_design(n, design_num)
|
150
|
-
|
151
|
-
num_columns = design[0].length
|
152
|
-
if num_stackings > num_columns
|
153
|
-
ErrorHandling.clean_abort [
|
154
|
-
'Requested stacking exceeds number of columns in FDE '.red +
|
155
|
-
"(#{num_columns})".red
|
156
|
-
]
|
157
|
-
end
|
158
|
-
|
159
|
-
num_stackings.times do |_stack_num|
|
160
|
-
design.each_with_index do |dp, i|
|
161
|
-
scaled_dp = dp.slice(0, n).map.with_index { |x, k| factor[k].scale(x) }
|
162
|
-
if csv_out
|
163
|
-
puts scaled_dp.join ','
|
164
|
-
else
|
165
|
-
puts scaled_dp.join "\t"
|
166
|
-
end
|
167
|
-
design[i] = dp.rotate
|
168
|
-
end
|
169
|
-
end
|
data/exe/scaled_rf_cubed.rb
DELETED
@@ -1,173 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -w
|
2
|
-
|
3
|
-
require 'colorize'
|
4
|
-
String.disable_colorization false
|
5
|
-
|
6
|
-
require_relative '../lib/datafarming/error_handling'
|
7
|
-
require_relative '../lib/datafarming/factorial_generator'
|
8
|
-
|
9
|
-
def print_descriptor
|
10
|
-
description = [
|
11
|
-
"\nCreate a Resolution V fractional factorial design, either in standard +/-1",
|
12
|
-
'notation or scaled as per user-provided input. The design can optionally ',
|
13
|
-
'be supplemented with CCD center and star points. Output is written to',
|
14
|
-
'stdout'.blue + ' with formatting controlled by command-line options.'
|
15
|
-
]
|
16
|
-
STDERR.puts description
|
17
|
-
end
|
18
|
-
|
19
|
-
def print_directions # :nodoc:
|
20
|
-
prog = $PROGRAM_NAME.split(/\//)[-1]
|
21
|
-
help_msg = [
|
22
|
-
'', 'Syntax:', '',
|
23
|
-
" ruby #{prog} [Options] #factors | low/high-settings".yellow, '',
|
24
|
-
"The vertical bar '|' indicates valid alternatives.", '',
|
25
|
-
'Command-line args must specify either:',
|
26
|
-
' - the number of factors for the design; or',
|
27
|
-
' - low and hi values for all factors.', '',
|
28
|
-
"\nOptions:",
|
29
|
-
' --help | -h | -? | ?'.green,
|
30
|
-
"\tProduce this help message.",
|
31
|
-
' --design-only | -d'.green,
|
32
|
-
"\tprint the design without labeling",
|
33
|
-
' --csv | -c'.green,
|
34
|
-
"\tprint the design as comma separated",
|
35
|
-
' --center | -a'.green,
|
36
|
-
"\tadd global center pt to check linearity",
|
37
|
-
' --star | -s'.green,
|
38
|
-
"\taugment with Central Composite Design pts (includes --center)",
|
39
|
-
' --rotatable | -r'.green,
|
40
|
-
"\tscale a CCD design to be rotatable (includes --star)",
|
41
|
-
''
|
42
|
-
]
|
43
|
-
STDERR.puts help_msg
|
44
|
-
end
|
45
|
-
|
46
|
-
(print_descriptor && print_directions && exit) if ARGV.empty?
|
47
|
-
begin
|
48
|
-
labels = true
|
49
|
-
csv = false
|
50
|
-
scaled = false
|
51
|
-
center = false
|
52
|
-
star = false
|
53
|
-
rotatable = false
|
54
|
-
fmt_size = '5'
|
55
|
-
fmt_type = 'd'
|
56
|
-
|
57
|
-
while ARGV[0] =~ /^(-\D|\?)/
|
58
|
-
arg = ARGV.shift
|
59
|
-
case arg
|
60
|
-
when '-c', '--csv'
|
61
|
-
csv = true
|
62
|
-
when '-d', '--design-only'
|
63
|
-
labels = false
|
64
|
-
when '-a', '--center'
|
65
|
-
center = true
|
66
|
-
when '-s', '--star'
|
67
|
-
star = true
|
68
|
-
center = true
|
69
|
-
when '-r', '--rotatable'
|
70
|
-
rotatable = true
|
71
|
-
star = true
|
72
|
-
center = true
|
73
|
-
fmt_size = '11.8'
|
74
|
-
fmt_type = 'f'
|
75
|
-
when '-h', '--help', '-?', '?'
|
76
|
-
print_descriptor
|
77
|
-
print_directions
|
78
|
-
exit
|
79
|
-
else
|
80
|
-
raise "Unknown option #{arg}"
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
if ARGV.empty?
|
85
|
-
raise 'Must specify a design size'
|
86
|
-
elsif ARGV.length == 1
|
87
|
-
n = ARGV.shift.to_i
|
88
|
-
elsif (ARGV.length & 1).nonzero? # Odd number of args remaining!
|
89
|
-
raise 'Number of levels is odd: low/hi values must occur in pairs'
|
90
|
-
else
|
91
|
-
n = ARGV.length / 2
|
92
|
-
scaled = true
|
93
|
-
unless rotatable
|
94
|
-
fmt_type = 's'
|
95
|
-
fmt_size = [ARGV.map(&:length).max + 1, fmt_size.to_i].max
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
my_design = make_design n
|
100
|
-
if rotatable && star
|
101
|
-
inverse_len = 1.0 / Math.sqrt(n)
|
102
|
-
my_design.each_with_index do |row, i|
|
103
|
-
my_design[i] = row.map { |elt| elt * inverse_len }
|
104
|
-
end
|
105
|
-
end
|
106
|
-
my_design += [Array.new(n, 0)] if center
|
107
|
-
|
108
|
-
if star
|
109
|
-
star_design = Array.new(2 * n)
|
110
|
-
star_design.each_index { |row| star_design[row] = Array.new(n, 0) }
|
111
|
-
n.times do |col|
|
112
|
-
row = 2 * col
|
113
|
-
star_design[row][col] = -1
|
114
|
-
star_design[row + 1][col] = 1
|
115
|
-
end
|
116
|
-
my_design += star_design
|
117
|
-
end
|
118
|
-
|
119
|
-
if scaled
|
120
|
-
temp = my_design.transpose
|
121
|
-
temp.each_with_index do |factor, idx|
|
122
|
-
factor.map! do |value|
|
123
|
-
case value
|
124
|
-
when -1
|
125
|
-
ARGV[2 * idx + 1]
|
126
|
-
when 1
|
127
|
-
ARGV[2 * idx]
|
128
|
-
when 0
|
129
|
-
begin
|
130
|
-
0.5 * (Float(ARGV[2 * idx + 1]) + Float(ARGV[2 * idx]))
|
131
|
-
rescue
|
132
|
-
raise 'All factors must be numeric for augmented designs.'
|
133
|
-
end
|
134
|
-
else
|
135
|
-
begin
|
136
|
-
lo = Float(ARGV[2 * idx])
|
137
|
-
hi = Float(ARGV[2 * idx + 1])
|
138
|
-
range = hi - lo
|
139
|
-
0.5 * (hi + lo + value * range)
|
140
|
-
rescue
|
141
|
-
raise 'All factors must be numeric for augmented designs.'
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
my_design = temp.transpose
|
147
|
-
end
|
148
|
-
|
149
|
-
if labels
|
150
|
-
if csv
|
151
|
-
print ' DP#'
|
152
|
-
n.times { |i| print ",X#{i + 1}" }
|
153
|
-
else
|
154
|
-
print ' DP#'
|
155
|
-
n.times { |i| printf " %#{fmt_size}s", "X#{i + 1}" }
|
156
|
-
end
|
157
|
-
puts
|
158
|
-
end
|
159
|
-
|
160
|
-
my_design.each_with_index do |design_point, row_number|
|
161
|
-
if csv
|
162
|
-
printf('%d,', row_number + 1) if labels
|
163
|
-
puts design_point.join(',')
|
164
|
-
else
|
165
|
-
printf('%5d', row_number + 1) if labels
|
166
|
-
design_point.each { |value| printf " %#{fmt_size}#{fmt_type}", value }
|
167
|
-
puts
|
168
|
-
end
|
169
|
-
end
|
170
|
-
rescue StandardError => e
|
171
|
-
STDERR.print "\n", e.message, "\n"
|
172
|
-
print_directions
|
173
|
-
end
|
data/exe/stack_nolhs.rb
DELETED
@@ -1,174 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -w
|
2
|
-
|
3
|
-
require 'colorize'
|
4
|
-
String.disable_colorization false
|
5
|
-
|
6
|
-
require 'datafarming/error_handling'
|
7
|
-
require 'datafarming/nolh_designs'
|
8
|
-
|
9
|
-
help_msg = [
|
10
|
-
'Generate scaled Latin hypercube designs with shifting and stacking. ',
|
11
|
-
'Results are a white-space delimited NOLH design written to ' +
|
12
|
-
'stdout'.light_blue + '.', '',
|
13
|
-
'Syntax:',
|
14
|
-
"\n\t#{$PROGRAM_NAME.split(%r{/|\\})[-1]} [--help]".yellow +
|
15
|
-
" [--stack #] [--levels #] [-e] [file_name]\n".yellow,
|
16
|
-
"Arguments in square brackets are optional. A vertical bar '|'",
|
17
|
-
'indicates valid alternatives for invoking the option. Prefix',
|
18
|
-
'the command with "' + 'ruby'.yellow +
|
19
|
-
'" if it is not on your PATH.', '',
|
20
|
-
' --help | -h | -? | ?'.green,
|
21
|
-
"\tProduce this help message. Supersedes any other choices.",
|
22
|
-
' --stack # | -s #'.green,
|
23
|
-
"\t# specifies the number of stackings. A value of 1 means print the",
|
24
|
-
"\tbase design. If this option is not specified the number of stackings",
|
25
|
-
"\tdefaults to the number of columns in the design. The specified value",
|
26
|
-
"\tcannot exceed the number of columns in the design being used.",
|
27
|
-
' --levels # | -l #'.green,
|
28
|
-
"\t# specifies the desired number of levels in the NOLH (17, 33, 65, 129,",
|
29
|
-
"\t257, or 512). Defaults to the smallest design which can accommodate the",
|
30
|
-
"\tnumber of factors if this option is not specified.",
|
31
|
-
' --excel-style-input | -e'.green,
|
32
|
-
"\tSpecify factor ranges and decimals as in the NOLH spreadsheet, i.e.,",
|
33
|
-
"\tthe first line is the set of minimum range values for each factor;",
|
34
|
-
"\tthe second line is maximum range values; and the third is the number",
|
35
|
-
"\tof decimal places to use for the range scaling. Without this option,",
|
36
|
-
"\tthe default input format is one line per factor, comprised of the min,",
|
37
|
-
"\tmax, and number of decimal places separated by commas or whitespace.",
|
38
|
-
' file_name'.green,
|
39
|
-
"\tThe name of a file containing the factor specifications. If no",
|
40
|
-
"\tfilename is given, the user can enter the values interactively in",
|
41
|
-
"\tthe desired form or use file redirection with '<'.", '',
|
42
|
-
'Options may be given in any order, but must come before the file name',
|
43
|
-
'if one is provided.'
|
44
|
-
]
|
45
|
-
|
46
|
-
# Scaler objects will rescale a Latin Hypercube design from standard units
|
47
|
-
# to a range as specified by min, max, and num_decimals
|
48
|
-
class Scaler
|
49
|
-
def initialize(min, max, num_decimals, lh_max = 17)
|
50
|
-
@min = min
|
51
|
-
@range = (max - min) / (lh_max - 1).to_r
|
52
|
-
@scale_factor = 10.to_r**num_decimals
|
53
|
-
end
|
54
|
-
|
55
|
-
def scale(value)
|
56
|
-
new_value = @min + @range * (value.to_r - 1.to_r)
|
57
|
-
if @scale_factor == 1
|
58
|
-
new_value.round
|
59
|
-
else
|
60
|
-
((@scale_factor * new_value).round / @scale_factor).to_f
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
excel_style_inputs = false
|
66
|
-
while ARGV[0] && (ARGV[0][0] == '-' || ARGV[0][0] == 45 || ARGV[0][0] == '?')
|
67
|
-
current_value = ARGV.shift
|
68
|
-
case current_value
|
69
|
-
when '--stack', '-s'
|
70
|
-
num_stackings = ARGV.shift.to_i
|
71
|
-
when '--levels', '-l'
|
72
|
-
lh_levels = ARGV.shift.to_i
|
73
|
-
unless NOLH::DESIGN_TABLE.keys.include?(lh_levels)
|
74
|
-
ErrorHandling.clean_abort [
|
75
|
-
"Invalid number of levels for Latin hypercube: #{lh_levels}".red,
|
76
|
-
'Use 17, 33, 65, 129, 257, or 512.'.yellow
|
77
|
-
]
|
78
|
-
end
|
79
|
-
when '--excel-style-input', '-e'
|
80
|
-
excel_style_inputs = true
|
81
|
-
when '--help', '-h', '-help', '-?', '?'
|
82
|
-
ErrorHandling.clean_abort help_msg
|
83
|
-
else
|
84
|
-
ErrorHandling.message ['Unknown argument: '.red + current_value.yellow]
|
85
|
-
ErrorHandling.clean_abort help_msg
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
begin
|
90
|
-
if excel_style_inputs
|
91
|
-
if ARGV.empty?
|
92
|
-
STDERR.puts 'Enter one line of min values, one of max values,'.green +
|
93
|
-
' and one of #decimals.'.green
|
94
|
-
end
|
95
|
-
min_values = ARGF.gets.strip.split(/\s*[,;:]\s*|\s+/).map(&:to_f)
|
96
|
-
max_values = ARGF.gets.strip.split(/\s*[,;:]\s*|\s+/).map(&:to_f)
|
97
|
-
decimals = ARGF.gets.strip.split(/\s*[,;:]\s*|\s+/).map(&:to_i)
|
98
|
-
else
|
99
|
-
if ARGV.empty?
|
100
|
-
STDERR.puts 'To terminate input enter '.green + 'ctrl-d'.cyan +
|
101
|
-
' (Mac/Unix/Linux)'.green + ' or '.green + 'ctrl-z'.cyan +
|
102
|
-
' (Windows).'.green
|
103
|
-
STDERR.puts 'Enter ranges for each factor on a separate line.'.green
|
104
|
-
STDERR.puts "\nMIN\tMAX\t#DIGITS".cyan
|
105
|
-
end
|
106
|
-
min_values = []
|
107
|
-
max_values = []
|
108
|
-
decimals = []
|
109
|
-
while line = ARGF.gets
|
110
|
-
values = line.strip.split(/\s*[,;:]\s*|\s+/)
|
111
|
-
min_values << values.shift.to_f
|
112
|
-
max_values << values.shift.to_f
|
113
|
-
decimals << values.shift.to_i
|
114
|
-
end
|
115
|
-
end
|
116
|
-
rescue StandardError => e
|
117
|
-
ErrorHandling.message [e.message.red]
|
118
|
-
ErrorHandling.clean_abort help_msg
|
119
|
-
end
|
120
|
-
|
121
|
-
n = min_values.size
|
122
|
-
if max_values.size != n || decimals.size != n
|
123
|
-
ErrorHandling.message ['Unequal counts for min, max, and decimals'.red]
|
124
|
-
ErrorHandling.clean_abort help_msg
|
125
|
-
end
|
126
|
-
minimal_size = case min_values.size
|
127
|
-
when 1..7
|
128
|
-
17
|
129
|
-
when 8..11
|
130
|
-
33
|
131
|
-
when 12..16
|
132
|
-
65
|
133
|
-
when 17..22
|
134
|
-
129
|
135
|
-
when 23..29
|
136
|
-
257
|
137
|
-
when 30..100
|
138
|
-
512
|
139
|
-
else
|
140
|
-
ErrorHandling.message ['invalid number of factors'.red]
|
141
|
-
ErrorHandling.clean_abort help_msg
|
142
|
-
end
|
143
|
-
|
144
|
-
lh_levels ||= minimal_size
|
145
|
-
|
146
|
-
if lh_levels < minimal_size
|
147
|
-
ErrorHandling.clean_abort [
|
148
|
-
"Latin hypercube with #{lh_levels} levels is too small for #{n} factors.".red
|
149
|
-
]
|
150
|
-
end
|
151
|
-
|
152
|
-
factor = Array.new(n) do |i|
|
153
|
-
Scaler.new(min_values[i], max_values[i], decimals[i], lh_levels)
|
154
|
-
end
|
155
|
-
|
156
|
-
design = NOLH::DESIGN_TABLE[lh_levels]
|
157
|
-
|
158
|
-
num_columns = design[0].length
|
159
|
-
num_stackings ||= num_columns
|
160
|
-
if num_stackings > num_columns
|
161
|
-
ErrorHandling.clean_abort [
|
162
|
-
'Requested stacking exceeds number of columns in latin hypercube '.red +
|
163
|
-
"(#{num_columns})".red
|
164
|
-
]
|
165
|
-
end
|
166
|
-
|
167
|
-
mid_range = lh_levels / 2
|
168
|
-
num_stackings.times do |stack_num|
|
169
|
-
design.each_with_index do |dp, i|
|
170
|
-
scaled_dp = dp.slice(0, n).map.with_index { |x, k| factor[k].scale(x) }
|
171
|
-
puts scaled_dp.join "\t" unless stack_num > 0 && i == mid_range && lh_levels < 512
|
172
|
-
design[i] = dp.rotate
|
173
|
-
end
|
174
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
require 'fwt'
|
2
|
-
|
3
|
-
# Generate a Resolution V Fractional Factorial design for the specified
|
4
|
-
# number of factors. The design is guaranteed to yield unconfounded
|
5
|
-
# interactions for all pairs of factors. The design uses standardized
|
6
|
-
# notation, i.e., -1 represents a low setting and 1 represents a high
|
7
|
-
# setting for each factor.
|
8
|
-
#
|
9
|
-
# *Arguments*::
|
10
|
-
# - +number_of_factors+ -> the number of factors in your design. Limit is 120.
|
11
|
-
# *Returns*::
|
12
|
-
# - a two-dimensional array specifying the design, where each column
|
13
|
-
# corresponds to a factor and each row is a design point.
|
14
|
-
#
|
15
|
-
# Author:: Paul J Sanchez (mailto:pjs@alum.mit.edu)
|
16
|
-
# Copyright:: Copyright (c) 2020 Paul J Sanchez
|
17
|
-
# License:: MIT
|
18
|
-
#
|
19
|
-
INDEX = [1, 2, 4, 8, 15, 16, 32, 51, 64, 85, 106, 128, 150, 171,
|
20
|
-
219, 237, 247, 256, 279, 297, 455, 512, 537, 557, 594, 643, 803,
|
21
|
-
863, 998, 1024, 1051, 1070, 1112, 1169, 1333, 1345, 1620, 1866,
|
22
|
-
2048, 2076, 2085, 2185, 2372, 2456, 2618, 2800, 2873, 3127, 3284,
|
23
|
-
3483, 3557, 3763, 4096, 4125, 4135, 4174, 4435, 4459, 4469, 4497,
|
24
|
-
4752, 5255, 5732, 5804, 5915, 6100, 6369, 6907, 7069, 8192, 8263,
|
25
|
-
8351, 8422, 8458, 8571, 8750, 8858, 9124, 9314, 9500, 10_026,
|
26
|
-
10_455, 10_556, 11_778, 11_885, 11_984, 13_548, 14_007, 14_514,
|
27
|
-
14_965, 15_125, 15_554, 16_384, 16_457, 16_517, 16_609, 16_771,
|
28
|
-
16_853, 17_022, 17_453, 17_891, 18_073, 18_562, 18_980, 19_030,
|
29
|
-
19_932, 20_075, 20_745, 21_544, 22_633, 23_200, 24_167, 25_700,
|
30
|
-
26_360, 26_591, 26_776, 28_443, 28_905, 29_577, 32_705]
|
31
|
-
POWER = [1, 2, 4, 8, 16, 16, 32, 64, 64, 128, 128, 128, 256, 256,
|
32
|
-
256, 256, 256, 256, 512, 512, 512, 512, 1024, 1024, 1024, 1024,
|
33
|
-
1024, 1024, 1024, 1024, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
|
34
|
-
2048, 2048, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096,
|
35
|
-
4096, 4096, 4096, 4096, 4096, 8192, 8192, 8192, 8192, 8192, 8192,
|
36
|
-
8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
|
37
|
-
16_384, 16_384, 16_384, 16_384, 16_384, 16_384, 16_384, 16_384,
|
38
|
-
16_384, 16_384, 16_384, 16_384, 16_384, 16_384, 16_384, 16_384,
|
39
|
-
16_384, 16_384, 16_384, 16_384, 16_384, 16_384, 16_384, 32_768,
|
40
|
-
32_768, 32_768, 32_768, 32_768, 32_768, 32_768, 32_768, 32_768,
|
41
|
-
32_768, 32_768, 32_768, 32_768, 32_768, 32_768, 32_768, 32_768,
|
42
|
-
32_768, 32_768, 32_768, 32_768, 32_768, 32_768, 32_768, 32_768,
|
43
|
-
32_768, 32_768, 32_768]
|
44
|
-
|
45
|
-
def make_design(number_of_factors)
|
46
|
-
Array.new(number_of_factors) do |i|
|
47
|
-
Array.new(POWER[number_of_factors], 0).tap { |a| a[INDEX[i]] = 1 }.hadamard
|
48
|
-
end.transpose
|
49
|
-
end
|