statsample-bivariate-extension 0.16.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/.gemtest +0 -0
- data/Manifest.txt +0 -1
- data/Rakefile +1 -0
- data/lib/statsample/bivariate/extension_version.rb +1 -1
- data/lib/statsample/bivariate/polychoric.rb +32 -19
- data/lib/statsample/bivariate/polychoric/processor.rb +2 -2
- data/lib/statsample/bivariate/tetrachoric.rb +4 -4
- data/spec/tetrachoric_spec.rb +6 -3
- metadata +120 -104
- metadata.gz.sig +0 -0
- data/grab_references.rb +0 -28
data.tar.gz.sig
CHANGED
Binary file
|
data/.gemtest
ADDED
File without changes
|
data/Manifest.txt
CHANGED
data/Rakefile
CHANGED
@@ -15,6 +15,7 @@ Hoe.spec 'statsample-bivariate-extension' do
|
|
15
15
|
self.rubyforge_name = 'ruby-statsample'
|
16
16
|
self.version=Statsample::Bivariate::EXTENSION_VERSION
|
17
17
|
self.developer('Claudio Bustos', 'clbustos_at_gmail.com')
|
18
|
+
self.extra_deps << ["distribution", "~>0.6"]
|
18
19
|
end
|
19
20
|
|
20
21
|
# vim: syntax=ruby
|
@@ -140,6 +140,8 @@ module Statsample
|
|
140
140
|
# Returns the columns thresholds
|
141
141
|
attr_reader :beta
|
142
142
|
|
143
|
+
attr_reader :failed
|
144
|
+
|
143
145
|
dirty_writer :max_iterations, :epsilon, :minimizer_type_two_step, :minimizer_type_joint_no_derivative, :minimizer_type_joint_derivative, :method
|
144
146
|
dirty_memoize :r, :alpha, :beta
|
145
147
|
# Default method
|
@@ -185,6 +187,7 @@ module Statsample
|
|
185
187
|
}
|
186
188
|
@r=nil
|
187
189
|
@pd=nil
|
190
|
+
@failed=false
|
188
191
|
compute_basic_parameters
|
189
192
|
end
|
190
193
|
|
@@ -435,6 +438,8 @@ module Statsample
|
|
435
438
|
message+=sprintf("%10.3e ", x[i])
|
436
439
|
end
|
437
440
|
message+=sprintf("f() = %7.3f\n" , minimizer.f)+"\n";
|
441
|
+
rescue => e
|
442
|
+
@failed=true
|
438
443
|
end while status == GSL::CONTINUE and iter < @max_iterations
|
439
444
|
|
440
445
|
@iteration=iter
|
@@ -527,7 +532,7 @@ module Statsample
|
|
527
532
|
pc=@nr.times.collect{ [0]*@nc}
|
528
533
|
@nr.times { |i|
|
529
534
|
@nc.times { |j|
|
530
|
-
pd[i][j]=Distribution::
|
535
|
+
pd[i][j]=Distribution::BivariateNormal.cdf(@alpha[i], @beta[j], rho)
|
531
536
|
pc[i][j] = pd[i][j]
|
532
537
|
pd[i][j] = pd[i][j] - pc[i-1][j] if i>0
|
533
538
|
pd[i][j] = pd[i][j] - pc[i][j-1] if j>0
|
@@ -819,26 +824,34 @@ module Statsample
|
|
819
824
|
|
820
825
|
def report_building(generator) # :nodoc:
|
821
826
|
compute if dirty?
|
827
|
+
|
828
|
+
|
822
829
|
section=ReportBuilder::Section.new(:name=>@name)
|
823
|
-
|
824
|
-
@
|
825
|
-
|
830
|
+
|
831
|
+
if @failed
|
832
|
+
section.add("Failed to converge")
|
833
|
+
else
|
834
|
+
t=ReportBuilder::Table.new(:name=>_("Contingence Table"), :header=>[""]+(@n.times.collect {|i| "Y=#{i}"})+["Total"])
|
835
|
+
@m.times do |i|
|
836
|
+
t.row(["X = #{i}"]+(@n.times.collect {|j| @matrix[i,j]}) + [@sumr[i]])
|
837
|
+
end
|
838
|
+
t.hr
|
839
|
+
t.row(["T"]+(@n.times.collect {|j| @sumc[j]})+[@total])
|
840
|
+
section.add(t)
|
841
|
+
section.add(sprintf("r: %0.4f",r))
|
842
|
+
t=ReportBuilder::Table.new(:name=>_("Thresholds"), :header=>["","Value"])
|
843
|
+
threshold_x.each_with_index {|val,i|
|
844
|
+
t.row([_("Threshold X %d") % i, sprintf("%0.4f", val)])
|
845
|
+
}
|
846
|
+
threshold_y.each_with_index {|val,i|
|
847
|
+
t.row([_("Threshold Y %d") % i, sprintf("%0.4f", val)])
|
848
|
+
}
|
849
|
+
section.add(t)
|
850
|
+
section.add(_("Iterations: %d") % @iteration) if @iteration
|
851
|
+
section.add(_("Test of bivariate normality: X^2 = %0.3f, df = %d, p= %0.5f" % [ chi_square, chi_square_df, 1-Distribution::ChiSquare.cdf(chi_square, chi_square_df)]))
|
852
|
+
generator.parse_element(section)
|
826
853
|
end
|
827
|
-
|
828
|
-
t.row(["T"]+(@n.times.collect {|j| @sumc[j]})+[@total])
|
829
|
-
section.add(t)
|
830
|
-
section.add(sprintf("r: %0.4f",r))
|
831
|
-
t=ReportBuilder::Table.new(:name=>_("Thresholds"), :header=>["","Value"])
|
832
|
-
threshold_x.each_with_index {|val,i|
|
833
|
-
t.row([_("Threshold X %d") % i, sprintf("%0.4f", val)])
|
834
|
-
}
|
835
|
-
threshold_y.each_with_index {|val,i|
|
836
|
-
t.row([_("Threshold Y %d") % i, sprintf("%0.4f", val)])
|
837
|
-
}
|
838
|
-
section.add(t)
|
839
|
-
section.add(_("Iterations: %d") % @iteration)
|
840
|
-
section.add(_("Test of bivariate normality: X^2 = %0.3f, df = %d, p= %0.5f" % [ chi_square, chi_square_df, 1-Distribution::ChiSquare.cdf(chi_square, chi_square_df)]))
|
841
|
-
generator.parse_element(section)
|
854
|
+
|
842
855
|
end
|
843
856
|
end
|
844
857
|
end
|
@@ -16,7 +16,7 @@ module Statsample
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def bipdf(i,j)
|
19
|
-
Distribution::
|
19
|
+
Distribution::BivariateNormal.pdf(a(i), b(j), rho)
|
20
20
|
end
|
21
21
|
|
22
22
|
def loglike
|
@@ -111,7 +111,7 @@ module Statsample
|
|
111
111
|
a=(i==@nr-1) ? 100: alpha[i]
|
112
112
|
b=(j==@nc-1) ? 100: beta[j]
|
113
113
|
#puts "a:#{a} b:#{b}"
|
114
|
-
@pd[i][j]=Distribution::
|
114
|
+
@pd[i][j]=Distribution::BivariateNormal.cdf(a, b, rho)
|
115
115
|
end
|
116
116
|
pc[i][j] = @pd[i][j]
|
117
117
|
@pd[i][j] = @pd[i][j] - pc[i-1][j] if i>0
|
@@ -170,8 +170,8 @@ module Statsample
|
|
170
170
|
def compute_optimized
|
171
171
|
check_frequencies
|
172
172
|
t=Statsample::STATSAMPLE__.tetrachoric(@a,@b,@c,@d)
|
173
|
-
raise "Error on calculation of tetrachoric correlation: #{t[
|
174
|
-
@r,@sdr,@itype,@ifault,@zab, @zac = t[
|
173
|
+
raise "Error on calculation of tetrachoric correlation: #{t[:ifault]}" if t[:ifault]>0
|
174
|
+
@r,@sdr,@itype,@ifault,@zab, @zac = t[:r],t[:sdr],t[:itype],t[:ifault], t[:threshold_x], t[:threshold_y]
|
175
175
|
end
|
176
176
|
def check_frequencies
|
177
177
|
#
|
@@ -265,8 +265,8 @@ module Statsample
|
|
265
265
|
# COMPUTE NORMAL DEVIATES FOR THE MARGINAL FREQUENCIES
|
266
266
|
# SINCE NO MARGINAL CAN BE 0.0, IE IS NOT CHECKED
|
267
267
|
#
|
268
|
-
@zac = Distribution::Normal.p_value(@probac)
|
269
|
-
@zab = Distribution::Normal.p_value(@probab)
|
268
|
+
@zac = Distribution::Normal.p_value(@probac.to_f)
|
269
|
+
@zab = Distribution::Normal.p_value(@probab.to_f)
|
270
270
|
@ss = Math::exp(-0.5 * (@zac ** 2 + @zab ** 2)).quo(TWOPI)
|
271
271
|
#
|
272
272
|
# WHEN R IS 0.0, 1.0 OR -1.0, TRANSFER TO COMPUTE SDZERO
|
data/spec/tetrachoric_spec.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
$:.unshift(File.dirname(__FILE__)+"/../../")
|
2
|
-
require 'spec_helper'
|
2
|
+
require File.expand_path(File.dirname(__FILE__)+'/spec_helper')
|
3
3
|
|
4
4
|
describe "Statsample::Bivariate tetrachoric extensions" do
|
5
|
+
before do
|
6
|
+
@data_file=File.expand_path(File.dirname(__FILE__)+"/../data/tetmat_test.txt")
|
7
|
+
end
|
5
8
|
it "should respond to tetrachoric method" do
|
6
9
|
Statsample::Bivariate.should respond_to(:tetrachoric)
|
7
10
|
end
|
8
11
|
it "should return correct tetrachoric_matrix"do
|
9
|
-
ds=Statsample::PlainText.read(
|
12
|
+
ds=Statsample::PlainText.read(@data_file, %w{a b c d e})
|
10
13
|
tcm_obs=Statsample::Bivariate.tetrachoric_correlation_matrix(ds)
|
11
|
-
tcm_exp=Statsample::PlainText.read(
|
14
|
+
tcm_exp=Statsample::PlainText.read(@data_file, %w{a b c d e}).to_matrix
|
12
15
|
tcm_obs.row_size.times do |i|
|
13
16
|
tcm_obs.column_size do |j|
|
14
17
|
tcm_obs[i,j].should be_within( 0.00001).of(tcm_exp[i,k])
|
metadata
CHANGED
@@ -1,127 +1,143 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: statsample-bivariate-extension
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 16
|
9
|
-
- 1
|
10
|
-
version: 0.16.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Claudio Bustos
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
|
-
cert_chain:
|
17
|
-
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
11
|
+
cert_chain:
|
12
|
+
- !binary |-
|
13
|
+
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNakNDQWhxZ0F3SUJB
|
14
|
+
Z0lCQURBTkJna3Foa2lHOXcwQkFRVUZBREEvTVJFd0R3WURWUVFEREFoamJH
|
15
|
+
SjEKYzNSdmN6RVZNQk1HQ2dtU0pvbVQ4aXhrQVJrV0JXZHRZV2xzTVJNd0VR
|
16
|
+
WUtDWkltaVpQeUxHUUJHUllEWTI5dApNQjRYRFRFd01ETXlPVEl4TXpnMU5W
|
17
|
+
b1hEVEV4TURNeU9USXhNemcxTlZvd1B6RVJNQThHQTFVRUF3d0lZMnhpCmRY
|
18
|
+
TjBiM014RlRBVEJnb0praWFKay9Jc1pBRVpGZ1ZuYldGcGJERVRNQkVHQ2dt
|
19
|
+
U0pvbVQ4aXhrQVJrV0EyTnYKYlRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFB
|
20
|
+
RGdnRVBBRENDQVFvQ2dnRUJBTGY4SlZNR3FFN201a1liK1BOTgpuZVp2MnBj
|
21
|
+
WFY1ZlFDaTZ4a3lHOGJpMi9TSUZ5L0x5eHV2THpFZU94QmVhejFCZTkzYmF5
|
22
|
+
SVVxdU9JcXczZHl3Ci9LWFdhMzFGeHVOdXZBbTZDTjhmeWVSWVgvb3U0Y3cz
|
23
|
+
T0lVVW5JdkI3Uk1OSXU0d2JnZU02aHRWL1FFc05McnYKYXQxL21oOUpwcWF3
|
24
|
+
UHJjaklPVk1qNEJJcDY3dm16SkNhVWYrUy9IMnVZdFNPMDlGK1lRRTN0djg1
|
25
|
+
VFBlUm1xVQp5anlYeVRjL29KaXcxY1hza1VMOFV0TVdabXJ3TkxIWHVaV1dJ
|
26
|
+
TXpraml6M1VOZGhKci90NVJPazhTMldQem5sCjBiTXkvUE1JbEFicVdvbFJu
|
27
|
+
MXpsMlZGSjNUYVhTY2JxSW1ZOFdmNGc2MmIvMVpTVWxHcnRuTE5zQ1lYcldp
|
28
|
+
c28KVVBVQ0F3RUFBYU01TURjd0NRWURWUjBUQkFJd0FEQUxCZ05WSFE4RUJB
|
29
|
+
TUNCTEF3SFFZRFZSME9CQllFRkd1OQpyckoxSDY0cVJtTk51M0pqL1Fqdmgw
|
30
|
+
dTVNQTBHQ1NxR1NJYjNEUUVCQlFVQUE0SUJBUUNWMFVua2E1aXNyaFprCkdq
|
31
|
+
cVNEcVkvNmhGK0cycGJGY2JXVXBqbUM4Tld0QXhlQys3TkdWM2xqZDBlMVNM
|
32
|
+
Zm95Qmo0Z25GdEZtWThxWDQKSzAydGdTWk0wZURWOFRwZ0ZwV1h6SzZMekh2
|
33
|
+
b2FudWFoSExaRXRrLytaODg1bEZlbmUrbkhhZGtlbTFuOWlBQgpjczk2Sk85
|
34
|
+
L0pmRnl1WE0yN3dGQXdtZkhDbUpmUEYwOVI0VnZHSFJBdmI4TUd6U1ZnazJp
|
35
|
+
MDZPSlRxa0JUd3Z2CkpISmRveXczKzhidzlSSitqTGFOb1EreHUrMXBRZFMy
|
36
|
+
YmIzbTd4alpwdWZtbC9tOHpGQ3RqWU0vN3Fna0tSOHoKL1padDhsQ2lLZkZB
|
37
|
+
cnBwUnJaYXlFMkZWc3BzNFg2V3dCZHJLVE1aMENLU1hUUmN0YkVqMUJBWjY3
|
38
|
+
ZW9UdkJCdApycFAwampzMAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
|
39
|
+
date: 2011-09-12 00:00:00.000000000 Z
|
40
|
+
dependencies:
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: distribution
|
43
|
+
requirement: &15403740 !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ~>
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0.6'
|
49
|
+
type: :runtime
|
44
50
|
prerelease: false
|
45
|
-
|
51
|
+
version_requirements: *15403740
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: hoe
|
54
|
+
requirement: &15402800 !ruby/object:Gem::Requirement
|
46
55
|
none: false
|
47
|
-
requirements:
|
48
|
-
- -
|
49
|
-
- !ruby/object:Gem::Version
|
50
|
-
|
51
|
-
segments:
|
52
|
-
- 2
|
53
|
-
- 8
|
54
|
-
- 0
|
55
|
-
version: 2.8.0
|
56
|
+
requirements:
|
57
|
+
- - ~>
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '2.12'
|
56
60
|
type: :development
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
email:
|
61
|
+
prerelease: false
|
62
|
+
version_requirements: *15402800
|
63
|
+
description: !binary |-
|
64
|
+
UHJvdmlkZXMgYWR2YW5jZWQgYml2YXJpYXRlIHN0YXRpc3RpY3M6CiogVGV0
|
65
|
+
cmFjaG9yaWMgY29ycmVsYXRpb24KKiBQb2x5Y2hvcmljIGNvcnJlbGF0aW9u
|
66
|
+
email:
|
63
67
|
- clbustos_at_gmail.com
|
64
68
|
executables: []
|
65
|
-
|
66
69
|
extensions: []
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
-
|
71
|
-
|
72
|
-
-
|
73
|
-
|
74
|
-
-
|
75
|
-
|
76
|
-
|
77
|
-
-
|
78
|
-
|
79
|
-
-
|
80
|
-
|
81
|
-
-
|
82
|
-
|
83
|
-
-
|
84
|
-
|
85
|
-
-
|
86
|
-
|
87
|
-
-
|
88
|
-
|
89
|
-
-
|
90
|
-
|
91
|
-
|
92
|
-
|
70
|
+
extra_rdoc_files:
|
71
|
+
- !binary |-
|
72
|
+
SGlzdG9yeS50eHQ=
|
73
|
+
- !binary |-
|
74
|
+
TWFuaWZlc3QudHh0
|
75
|
+
- !binary |-
|
76
|
+
UkVBRE1FLnR4dA==
|
77
|
+
- !binary |-
|
78
|
+
cmVmZXJlbmNlcy50eHQ=
|
79
|
+
files:
|
80
|
+
- !binary |-
|
81
|
+
SGlzdG9yeS50eHQ=
|
82
|
+
- !binary |-
|
83
|
+
TWFuaWZlc3QudHh0
|
84
|
+
- !binary |-
|
85
|
+
UkVBRE1FLnR4dA==
|
86
|
+
- !binary |-
|
87
|
+
UmFrZWZpbGU=
|
88
|
+
- !binary |-
|
89
|
+
ZGF0YS90ZXRtYXRfbWF0cml4LnR4dA==
|
90
|
+
- !binary |-
|
91
|
+
ZGF0YS90ZXRtYXRfdGVzdC50eHQ=
|
92
|
+
- !binary |-
|
93
|
+
bGliL3N0YXRzYW1wbGUvYml2YXJpYXRlL2V4dGVuc2lvbl92ZXJzaW9uLnJi
|
94
|
+
- !binary |-
|
95
|
+
bGliL3N0YXRzYW1wbGUvYml2YXJpYXRlL3BvbHljaG9yaWMucmI=
|
96
|
+
- !binary |-
|
97
|
+
bGliL3N0YXRzYW1wbGUvYml2YXJpYXRlL3BvbHljaG9yaWMvcHJvY2Vzc29y
|
98
|
+
LnJi
|
99
|
+
- !binary |-
|
100
|
+
bGliL3N0YXRzYW1wbGUvYml2YXJpYXRlL3RldHJhY2hvcmljLnJi
|
101
|
+
- !binary |-
|
102
|
+
cmVmZXJlbmNlcy50eHQ=
|
103
|
+
- !binary |-
|
104
|
+
c3BlYy9wb2x5Y2hvcmljX3Byb2Nlc3Nvcl9zcGVjLnJi
|
105
|
+
- !binary |-
|
106
|
+
c3BlYy9wb2x5Y2hvcmljX3NwZWMucmI=
|
107
|
+
- !binary |-
|
108
|
+
c3BlYy9zcGVjLm9wdHM=
|
109
|
+
- !binary |-
|
110
|
+
c3BlYy9zcGVjX2hlbHBlci5yYg==
|
111
|
+
- !binary |-
|
112
|
+
c3BlYy90ZXRyYWNob3JpY19zcGVjLnJi
|
113
|
+
- .gemtest
|
114
|
+
homepage: !binary |-
|
115
|
+
aHR0cDovL3J1Ynktc3RhdHNhbXBsZS5ydWJ5Zm9yZ2Uub3JnLw==
|
93
116
|
licenses: []
|
94
|
-
|
95
117
|
post_install_message:
|
96
|
-
rdoc_options:
|
118
|
+
rdoc_options:
|
97
119
|
- --main
|
98
120
|
- README.txt
|
99
|
-
require_paths:
|
121
|
+
require_paths:
|
100
122
|
- lib
|
101
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
124
|
none: false
|
103
|
-
requirements:
|
104
|
-
- -
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
|
107
|
-
|
108
|
-
- 0
|
109
|
-
version: "0"
|
110
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ! '>='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
130
|
none: false
|
112
|
-
requirements:
|
113
|
-
- -
|
114
|
-
- !ruby/object:Gem::Version
|
115
|
-
|
116
|
-
segments:
|
117
|
-
- 0
|
118
|
-
version: "0"
|
131
|
+
requirements:
|
132
|
+
- - ! '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
119
135
|
requirements: []
|
120
|
-
|
121
136
|
rubyforge_project: ruby-statsample
|
122
|
-
rubygems_version: 1.
|
137
|
+
rubygems_version: 1.8.10
|
123
138
|
signing_key:
|
124
139
|
specification_version: 3
|
125
|
-
summary:
|
140
|
+
summary: !binary |-
|
141
|
+
UHJvdmlkZXMgYWR2YW5jZWQgYml2YXJpYXRlIHN0YXRpc3RpY3M6ICogVGV0
|
142
|
+
cmFjaG9yaWMgY29ycmVsYXRpb24gKiBQb2x5Y2hvcmljIGNvcnJlbGF0aW9u
|
126
143
|
test_files: []
|
127
|
-
|
metadata.gz.sig
CHANGED
Binary file
|
data/grab_references.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby1.9
|
2
|
-
require 'reportbuilder'
|
3
|
-
refs=[]
|
4
|
-
Dir.glob "**/*.rb" do |f|
|
5
|
-
reference=false
|
6
|
-
File.open(f).each_line do |l|
|
7
|
-
|
8
|
-
if l=~/== Reference/
|
9
|
-
reference=true
|
10
|
-
elsif reference
|
11
|
-
if l=~/\*\s+(.+)/
|
12
|
-
refs.push $1
|
13
|
-
else
|
14
|
-
reference=false
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
|
22
|
-
rb=ReportBuilder.new(:name=>"References") do |g|
|
23
|
-
refs.uniq.sort.each do |r|
|
24
|
-
g.text "* #{r}"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
rb.save_text("references.txt")
|