datafarming 1.4.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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.
@@ -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
@@ -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