num4anova 0.0.1-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 61d4380d19135d9bb9973755730f34794d2f4741882d494433086922de5fecbc
4
+ data.tar.gz: eed7345a3482c955c3537954fd6d053d2898f53bfc4807aa39926e23c407e3e2
5
+ SHA512:
6
+ metadata.gz: 756c787954a6c83b735781b4230b1f113bd3e944d7262e7dd2197cacf39bed1640555d5dfaa555552f6433f1b7905c2211948dc54ce5a1686520f23162316014
7
+ data.tar.gz: 878cd5056eed4258da283789036ebd0b209fc19e215a9e4bc6ffdf2d657bccecff858db6f4e4ad643ec215597e902edc20592bc5704cb906e693b720fe343d50
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Change Log
2
+
3
+ ## Unreleased
4
+
5
+ ## [0.0.2] - 2023-12-12
6
+
7
+ ### change
8
+ - chg Q-QPlot and kstest
9
+ - chg from one-side test to two side test.
10
+
11
+ ## [0.0.1] - 2023-12-05
12
+
13
+ ### Fixed
14
+ - fix first fixed.
15
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 siranovel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/javaextensiontask'
2
+
3
+ jars = Dir.glob("lib/*.jar")
4
+ Rake::JavaExtensionTask.new(name='num4anova') do | ext |
5
+ ext.release = '11'
6
+ ext.classpath = jars.map { |x| File.expand_path x }.join ":"
7
+ end
8
+ task :default => [:compile]
@@ -0,0 +1,248 @@
1
+ import org.jfree.chart.JFreeChart;
2
+ import org.jfree.chart.StandardChartTheme;
3
+ import org.jfree.chart.ChartFactory;
4
+ import org.jfree.data.statistics.BoxAndWhiskerCategoryDataset;
5
+ import org.jfree.data.statistics.DefaultBoxAndWhiskerCategoryDataset;
6
+ import org.jfree.data.statistics.BoxAndWhiskerCalculator;
7
+ import org.jfree.data.statistics.BoxAndWhiskerItem;
8
+ import org.jfree.data.category.CategoryDataset;
9
+ import org.jfree.data.category.DefaultCategoryDataset;
10
+ import org.jfree.chart.plot.CategoryPlot;
11
+ import org.jfree.chart.axis.ValueAxis;
12
+ import org.jfree.chart.renderer.category.BoxAndWhiskerRenderer;
13
+ import org.jfree.chart.labels.BoxAndWhiskerToolTipGenerator;
14
+ import org.jfree.chart.plot.PlotOrientation;
15
+ import org.jfree.chart.plot.DatasetRenderingOrder;
16
+ import org.jfree.chart.axis.CategoryAxis;
17
+ import org.jfree.chart.axis.NumberAxis;
18
+ import org.jfree.chart.renderer.category.LineAndShapeRenderer;
19
+ import org.jfree.chart.labels.StandardCategoryToolTipGenerator;
20
+ import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
21
+
22
+ import org.jfree.chart.ChartUtils;
23
+ import java.io.File;
24
+ import java.io.IOException;
25
+ import java.util.Arrays;
26
+ import java.util.List;
27
+ import java.util.ArrayList;
28
+
29
+ import org.apache.commons.math3.stat.inference.OneWayAnova;
30
+ import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
31
+ import org.apache.commons.math3.distribution.ChiSquaredDistribution;
32
+ import java.util.Map;
33
+ public class OneWayLayout {
34
+ private static OneWayLayout oneWay = new OneWayLayout();
35
+ public static OneWayLayout getInstance() {
36
+ return oneWay;
37
+ }
38
+ public void boxWhiskerPlot(String dname, Map<String, double[]> vals) {
39
+ ChartPlot plot = new BoxWhiskerChartPlot();
40
+ JFreeChart chart = plot.createChart("箱ひげ図", dname, vals);
41
+
42
+ plot.writeJPEG("boxWhisker.jpeg", chart, 500, 300);
43
+ }
44
+ public void oneWayScatterPlot(String dname, Map<String, double[]> vals) {
45
+ ChartPlot plot = new OneWayScatterChartPlot();
46
+ JFreeChart chart = plot.createChart("一元散布図", dname, vals);
47
+
48
+ plot.writeJPEG("scatter.jpeg", chart, 800, 500);
49
+ }
50
+ public boolean onewayanova(double[][] xi, double a) {
51
+ List<double[]> data = new ArrayList<double[]>();
52
+ OneWayAnova anova = new OneWayAnova();
53
+
54
+ Arrays.stream(xi).forEach(data::add);
55
+ return anova.anovaTest(data, a);
56
+ }
57
+ public boolean bartletTest(double[][] xi, double a) {
58
+ OneWayAnovaTest oneway = new BartletTest();
59
+
60
+ double statistic = oneway.calcTestStatistic(xi);
61
+ return oneway.test(statistic, a);
62
+ }
63
+ /*********************************/
64
+ /* interface define */
65
+ /*********************************/
66
+ private interface ChartPlot {
67
+ JFreeChart createChart(String title, String dname, Map<String, double[]> vals);
68
+ default void writeJPEG(String fname, JFreeChart chart, int width, int height) {
69
+ File file = new File(fname);
70
+ try {
71
+ ChartUtils.saveChartAsJPEG(file, chart, width, height);
72
+ } catch (IOException e) {
73
+ e.printStackTrace();
74
+ }
75
+ }
76
+ }
77
+ private interface CreatePlot {
78
+ CategoryPlot createPlot(String dname, Map<String, double[]> xi);
79
+ }
80
+ private interface OneWayAnovaTest {
81
+ double calcTestStatistic(double[][] xi);
82
+ boolean test(double statistic, double a);
83
+ }
84
+ /*********************************/
85
+ /* class define */
86
+ /*********************************/
87
+ // 箱ひげ図
88
+ private class BoxWhiskerChartPlot implements ChartPlot {
89
+ public JFreeChart createChart(String title, String dname, Map<String, double[]> vals) {
90
+ CategoryPlot plot = createPlot(dname, vals);
91
+ ChartFactory.setChartTheme(StandardChartTheme.createLegacyTheme());
92
+ JFreeChart chart = new JFreeChart(title, plot);
93
+
94
+ ChartUtils.applyCurrentTheme(chart);
95
+ return chart;
96
+ }
97
+ private CategoryPlot createPlot(String dname, Map<String, double[]> vals) {
98
+ CreatePlot plotImpl = new BoxWhiskerPlot();
99
+
100
+ return plotImpl.createPlot(dname, vals);
101
+ }
102
+ private class BoxWhiskerPlot implements CreatePlot {
103
+ public CategoryPlot createPlot(String dname, Map<String, double[]> vals) {
104
+ BoxAndWhiskerRenderer renderer0 = new BoxAndWhiskerRenderer();
105
+ renderer0.setDefaultToolTipGenerator(new BoxAndWhiskerToolTipGenerator());
106
+ renderer0.setMaximumBarWidth(0.2);
107
+
108
+ CategoryPlot plot = new CategoryPlot();
109
+ plot.setOrientation(PlotOrientation.VERTICAL);
110
+ plot.mapDatasetToRangeAxis(0,0);
111
+ plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
112
+
113
+ /*--- 横軸 ---*/
114
+ CategoryAxis categoryAxis = new CategoryAxis();
115
+ plot.setDomainAxis(categoryAxis);
116
+
117
+ /*--- 縦軸 ---*/
118
+ NumberAxis valueAxis = new NumberAxis();
119
+ valueAxis.setAutoRangeIncludesZero(false);
120
+ plot.setRangeAxis(valueAxis);
121
+
122
+
123
+ plot.setRenderer(0, renderer0);
124
+ plot.setDataset(0, createDataset(dname, vals));
125
+
126
+ return plot;
127
+ }
128
+ private BoxAndWhiskerCategoryDataset createDataset(String dname, Map<String, double[]> vals) {
129
+ DefaultBoxAndWhiskerCategoryDataset data =
130
+ new DefaultBoxAndWhiskerCategoryDataset();
131
+ List<Double> values = new ArrayList<Double>();
132
+ for(Map.Entry<String, double[]> entry : vals.entrySet()) {
133
+ double[] v = entry.getValue();
134
+
135
+ Arrays.stream(v).forEach(values::add);
136
+ data.add(
137
+ BoxAndWhiskerCalculator.calculateBoxAndWhiskerStatistics(values),
138
+ dname, entry.getKey()
139
+ );
140
+ values.clear();
141
+ }
142
+ return data;
143
+ }
144
+ }
145
+ }
146
+ // 一元配置グラフ
147
+ private class OneWayScatterChartPlot implements ChartPlot {
148
+ public JFreeChart createChart(String title, String dname, Map<String, double[]> vals) {
149
+ CategoryPlot plot = createPlot(dname, vals);
150
+
151
+ ChartFactory.setChartTheme(StandardChartTheme.createLegacyTheme());
152
+ JFreeChart chart = new JFreeChart(title, plot);
153
+
154
+ ChartUtils.applyCurrentTheme(chart);
155
+ return chart;
156
+ }
157
+ private CategoryPlot createPlot(String dname, Map<String, double[]> vals) {
158
+ CreatePlot plotImpl = new OneWayScatterPlot();
159
+
160
+ return plotImpl.createPlot(dname, vals);
161
+ }
162
+ private class OneWayScatterPlot implements CreatePlot {
163
+ public CategoryPlot createPlot(String dname, Map<String, double[]> vals) {
164
+ LineAndShapeRenderer renderer = new LineAndShapeRenderer(false, true);
165
+ renderer.setDefaultToolTipGenerator(
166
+ new StandardCategoryToolTipGenerator());
167
+
168
+ CategoryPlot plot = new CategoryPlot();
169
+ plot.setOrientation(PlotOrientation.VERTICAL);
170
+ plot.mapDatasetToRangeAxis(0,0);
171
+ plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
172
+
173
+ /*--- 横軸 ---*/
174
+ CategoryAxis categoryAxis = new CategoryAxis();
175
+ plot.setDomainAxis(categoryAxis);
176
+
177
+ /*--- 縦軸 ---*/
178
+ NumberAxis valueAxis0 = new NumberAxis();
179
+ plot.setRangeAxis(valueAxis0);
180
+
181
+ plot.setRenderer(0, renderer);
182
+ plot.setDataset(0, createDataset(dname, vals));
183
+ return plot;
184
+ }
185
+
186
+ private CategoryDataset createDataset(String dname, Map<String, double[]> vals) {
187
+ DefaultCategoryDataset data = new DefaultCategoryDataset();
188
+ for(Map.Entry<String, double[]> entry : vals.entrySet()) {
189
+ double[] v = entry.getValue();
190
+ for(int i = 0; i < v.length; i++) {
191
+ String rowKey = String.format("dt%02d", i);
192
+
193
+ data.addValue(v[i], rowKey, entry.getKey());
194
+ }
195
+ }
196
+ return data;
197
+ }
198
+ }
199
+ }
200
+ private class BartletTest implements OneWayAnovaTest {
201
+ private int n = 0;
202
+ public double calcTestStatistic(double[][] xi) {
203
+ n = xi.length;
204
+ double ln2L = logL(xi);
205
+
206
+ return calcB(ln2L, xi);
207
+ }
208
+ private double logL(double[][] xi) {
209
+ double[] si = new double[n];
210
+ DescriptiveStatistics stat = new DescriptiveStatistics();
211
+ double nisi2 = 0.0; // (Ni - 1)*si^2の合計
212
+ double nilogsi2 = 0.0; // (Ni - 1)*log(si^2)の合計
213
+ int sumN = 0;
214
+
215
+ for(int i = 0; i < n; i++) {
216
+ Arrays.stream(xi[i]).forEach(stat::addValue);
217
+ sumN += stat.getN();
218
+ si[i] = stat.getVariance();
219
+ nisi2 += (stat.getN() - 1) * si[i];
220
+ nilogsi2 += (stat.getN() - 1) * Math.log(si[i]);
221
+ stat.clear();
222
+ }
223
+ double sumNin = sumN - n;
224
+ return sumNin * (Math.log(nisi2 / sumNin) - nilogsi2 / sumNin);
225
+ }
226
+ private double calcB(double ln2L, double[][] xi) {
227
+ double invSumN = 0.0;
228
+ int sumN = 0;
229
+ DescriptiveStatistics stat = new DescriptiveStatistics();
230
+ for(int i = 0; i < n; i++) {
231
+ Arrays.stream(xi[i]).forEach(stat::addValue);
232
+ invSumN += 1.0 / (stat.getN() - 1.0);
233
+ sumN += stat.getN();
234
+ stat.clear();
235
+ }
236
+ double deno = 1 + 1.0 / (3 * (n - 1))
237
+ * (invSumN - 1.0 / (sumN - n));
238
+ return ln2L / deno;
239
+ }
240
+ public boolean test(double statistic, double a) {
241
+ ChiSquaredDistribution chi2Dist = new ChiSquaredDistribution(n - 1);
242
+ double r_val = chi2Dist.inverseCumulativeProbability(1.0 - a);
243
+
244
+ return (r_val < statistic) ? true : false;
245
+ }
246
+ }
247
+ }
248
+
Binary file
Binary file
Binary file
data/lib/num4anova.rb ADDED
@@ -0,0 +1,109 @@
1
+ require 'java'
2
+ require 'num4anova.jar'
3
+ require 'jfreechart-1.5.4.jar'
4
+ require 'commons-math3-3.6.1.jar'
5
+
6
+ java_import 'OneWayLayout'
7
+ java_import 'java.util.HashMap'
8
+ # 数値計算による分散分析を行う
9
+ module Num4AnovaLib
10
+ # 一元配置の分散分析
11
+ class OneWayLayoutLib
12
+ def initialize
13
+ @oneWay = OneWayLayout.getInstance()
14
+ end
15
+ # 箱ひげ図
16
+ #
17
+ # @overload boxWhiskerPlot(dname, vals)
18
+ # @param [String] dname データ名
19
+ # @param [Hash] vals Hash(String, double[])
20
+ # @return [void] boxWhisker.jpegファイルを出力
21
+ # @example
22
+ # vals = {
23
+ # "stage51" => [12.2, 18.8, 18.2],
24
+ # "stage55" => [22.2, 20.5, 14.6],
25
+ # "stage57" => [20.8, 19.5, 26.3],
26
+ # "stage59" => [26.4, 32.5, 31.3],
27
+ # "stage61" => [24.5, 21.2, 22.4],
28
+ # }
29
+ # oneWay = Num4AnovaLib::OneWayLayoutLib.new
30
+ # oneWay.boxWhiskerPlot("LDH", vals)
31
+ # => boxWhisker.jpeg
32
+ # @note
33
+ # グラフは、jfreechartを使用
34
+ def boxWhiskerPlot(dname, vals)
35
+ o = HashMap.new
36
+ vals.each{|k, v|
37
+ o[k] = v.to_java(Java::double)
38
+ }
39
+ @oneWay.boxWhiskerPlot(dname, o)
40
+ end
41
+ # 一元散布図
42
+ #
43
+ # @overload oneway_scatter_plot(dname, vals)
44
+ # @param [String] dname データ名
45
+ # @param [Hash] vals Hash(String, double[])
46
+ # @return [void] scatter.jpegファイルを出力
47
+ # @example
48
+ # vals = {
49
+ # "stage51" => [12.2, 18.8, 18.2],
50
+ # "stage55" => [22.2, 20.5, 14.6],
51
+ # "stage57" => [20.8, 19.5, 26.3],
52
+ # "stage59" => [26.4, 32.5, 31.3],
53
+ # "stage61" => [24.5, 21.2, 22.4],
54
+ # }
55
+ # oneWay = Num4AnovaLib::OneWayLayoutLib.new
56
+ # oneWay.oneway_scatter_plot("LDH", vals)
57
+ # => scatter.jpeg
58
+ # @note
59
+ # グラフは、jfreechartを使用
60
+ def oneway_scatter_plot(dname, vals)
61
+ o = HashMap.new
62
+ vals.each{|k, v|
63
+ o[k] = v.to_java(Java::double)
64
+ }
65
+ @oneWay.oneWayScatterPlot(dname, o)
66
+ end
67
+ # 一元配置分散分析
68
+ #
69
+ # @overload oneway_anova(xi, a)
70
+ # @param [array] xi データ(double[][])
71
+ # @param [double] a 有意水準
72
+ # @return [boolean] 検定結果(true:棄却域内 false:棄却域外)
73
+ # @example
74
+ # xi = [
75
+ # [12.2, 18.8, 18.2],
76
+ # [22.2, 20.5, 14.6],
77
+ # [20.8, 19.5, 26.3],
78
+ # [26.4, 32.5, 31.3],
79
+ # [24.5, 21.2, 22.4],
80
+ # ]
81
+ # oneWay = Num4AnovaLib::OneWayLayoutLib.new
82
+ # oneWay.oneWay.oneway_anova(xi, 0.05)
83
+ # => true
84
+ def oneway_anova(xi, a)
85
+ return @oneWay.onewayanova(xi.to_java(Java::double[]), a)
86
+ end
87
+ # バートレット検定
88
+ #
89
+ # @overload bartlet(xi, a)
90
+ # @param [array] xi データ(double[][])
91
+ # @param [double] a 有意水準
92
+ # @return [boolean] 検定結果(true:棄却域内 false:棄却域外)
93
+ # @example
94
+ # xi = [
95
+ # [12.2, 18.8, 18.2],
96
+ # [22.2, 20.5, 14.6],
97
+ # [20.8, 19.5, 26.3],
98
+ # [26.4, 32.5, 31.3],
99
+ # [24.5, 21.2, 22.4],
100
+ # ]
101
+ # oneWay = Num4AnovaLib::OneWayLayoutLib.new
102
+ # oneWay.bartlet(xi, 0.05)
103
+ # => true
104
+ def bartlet(xi, a)
105
+ return @oneWay.bartletTest(xi.to_java(Java::double[]), a)
106
+ end
107
+ end
108
+ end
109
+
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: num4anova
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: java
6
+ authors:
7
+ - siranovel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-01-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '12.3'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 12.3.3
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '12.3'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 12.3.3
33
+ - !ruby/object:Gem::Dependency
34
+ name: rake-compiler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.2'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 1.2.5
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '1.2'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 1.2.5
53
+ description: numerical solution for analysis of variance.
54
+ email: siranovel@gmail.com
55
+ executables: []
56
+ extensions:
57
+ - Rakefile
58
+ extra_rdoc_files: []
59
+ files:
60
+ - CHANGELOG.md
61
+ - Gemfile
62
+ - LICENSE
63
+ - Rakefile
64
+ - ext/num4anova/OneWayLayout.java
65
+ - lib/commons-math3-3.6.1.jar
66
+ - lib/jcommon-1.0.23.jar
67
+ - lib/jfreechart-1.5.4.jar
68
+ - lib/num4anova.rb
69
+ homepage: http://github.com/siranovel/num4varanly
70
+ licenses:
71
+ - MIT
72
+ metadata: {}
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubygems_version: 3.3.7
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: num for variance analysis
92
+ test_files: []