datafarming 1.3.0 → 2.1.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.
@@ -1,173 +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/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