num4normality 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: 6be725c6a9b20d5c4ca46f2543c96e293be67c9bcf2638816cb29331eadb8180
4
+ data.tar.gz: d18160bcab51e0760a2e4b533be709235f06d18b2150bb05cc4a9ef66a96179f
5
+ SHA512:
6
+ metadata.gz: 1e9c798eaa8043b712da5940f361c8adffa82f4436cccc34843286baad3109d481354fea2a8f6f914f4f8205f2ff0393c31f47cdde589cdb408506257ba06491
7
+ data.tar.gz: 9f257c671f62f84c224a03641d802d7f275a6d042c80d336f4a666283def61b53a169527c6ec854676ff3344da8e60bcb2a0e6716b8afa8e31d700172d91fed2
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # Change Log
2
+
3
+ ## Unreleased
4
+
5
+ ## [0.0.1] - 2023-12-05
6
+
7
+ ### Fixed
8
+ - fix first fixed.
9
+
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='num4normality') 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,313 @@
1
+ import org.jfree.chart.JFreeChart;
2
+ import org.jfree.chart.StandardChartTheme;
3
+ import org.jfree.chart.ChartFactory;
4
+ import org.jfree.data.xy.XYSeriesCollection;
5
+ import org.jfree.data.xy.XYSeries;
6
+
7
+ import org.jfree.chart.plot.XYPlot;
8
+ import org.jfree.chart.axis.NumberAxis;
9
+ import org.jfree.chart.axis.ValueAxis;
10
+ import org.jfree.chart.plot.PlotOrientation;
11
+ import org.jfree.chart.axis.NumberTickUnit;
12
+ import org.jfree.chart.labels.XYToolTipGenerator;
13
+ import org.jfree.chart.labels.StandardXYToolTipGenerator;
14
+ import org.jfree.chart.renderer.xy.XYItemRenderer;
15
+ import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
16
+ import org.jfree.chart.plot.DatasetRenderingOrder;
17
+
18
+ import org.jfree.chart.ChartUtils;
19
+ import java.io.File;
20
+ import java.io.IOException;
21
+
22
+ import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
23
+ import org.apache.commons.math3.distribution.NormalDistribution;
24
+ import java.util.Arrays;
25
+ import java.text.DecimalFormat;
26
+ public class Normality {
27
+ public static void qqplot(String dname, double[] xi) {
28
+ ChartPlot plot = new QQPlot();
29
+ JFreeChart chart = plot.createChart(dname, xi);
30
+
31
+ plot.writeJPEG("qqplot.jpeg", chart, 800, 500);
32
+ }
33
+ public static void kstest(String dname, double[] xi) {
34
+ ChartPlot plot = new KSTest();
35
+ JFreeChart chart = plot.createChart(dname, xi);
36
+
37
+ plot.writeJPEG("kstest.jpeg", chart, 800, 500);
38
+
39
+ }
40
+ public static boolean skewnesstest(double[] xi) {
41
+ DAgostinosTest daigo = new SkewnessTest();
42
+
43
+ double b1 = daigo.calcTestStatistic(xi);
44
+ return daigo.test(b1, 0.05);
45
+ }
46
+ public static boolean kurtosistest(double[] xi) {
47
+ DAgostinosTest daigo = new KurtosisTest();
48
+
49
+ double b2 = daigo.calcTestStatistic(xi);
50
+ return daigo.test(b2, 0.05);
51
+ }
52
+
53
+
54
+ private interface ChartPlot {
55
+ JFreeChart createChart(String dname, double[] xi);
56
+ default void writeJPEG(String fname, JFreeChart chart, int width, int height) {
57
+ File file = new File(fname);
58
+ try {
59
+ ChartUtils.saveChartAsJPEG(file, chart, width, height);
60
+ } catch (IOException e) {
61
+ e.printStackTrace();
62
+ }
63
+ }
64
+ }
65
+ private interface DAgostinosTest {
66
+ double calcTestStatistic(double[] xi);
67
+ boolean test(double statistic, double a);
68
+ }
69
+
70
+ // Q-Qplot
71
+ private static class QQPlot implements ChartPlot {
72
+ private DescriptiveStatistics stat = null;
73
+ private double m = 0.0;
74
+ private double sd = 0.0;
75
+ public QQPlot() {
76
+ stat = new DescriptiveStatistics();
77
+ }
78
+ public JFreeChart createChart(String dname, double[] xi) {
79
+ Arrays.stream(xi).forEach(stat::addValue);
80
+ m = stat.getMean(); // 平均
81
+ sd = stat.getStandardDeviation();// 標準偏差
82
+
83
+ XYPlot plot = createPlot(dname, xi);
84
+ /*--- 横軸 ---*/
85
+ NumberAxis domainAxis = new NumberAxis("標準正規分布");
86
+
87
+ plot.setDomainAxis(domainAxis);
88
+ domainAxis.setLowerMargin(0.03);
89
+ domainAxis.setUpperMargin(0.03);
90
+ domainAxis.setLowerBound(-4);
91
+ domainAxis.setUpperBound(4);
92
+
93
+ ChartFactory.setChartTheme(StandardChartTheme.createLegacyTheme());
94
+ return new JFreeChart("正規性の検定", plot);
95
+ }
96
+ private XYPlot createPlot(String dname, double[] xi) {
97
+ XYItemRenderer renderer0 = new XYLineAndShapeRenderer(false, true);
98
+ XYItemRenderer renderer1 = new XYLineAndShapeRenderer(true, false);
99
+ XYToolTipGenerator toolTipGenerator = new StandardXYToolTipGenerator();
100
+
101
+ renderer0.setDefaultToolTipGenerator(toolTipGenerator);
102
+ renderer0.setURLGenerator(null);
103
+ renderer1.setDefaultToolTipGenerator(toolTipGenerator);
104
+ renderer1.setURLGenerator(null);
105
+
106
+ XYPlot plot = new XYPlot();
107
+ plot.setOrientation(PlotOrientation.VERTICAL);
108
+ plot.mapDatasetToRangeAxis(0,0);
109
+ plot.mapDatasetToRangeAxis(1,0);
110
+ plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
111
+
112
+ /*--- 縦軸 ---*/
113
+ NumberAxis valueAxis0 = new NumberAxis("観測値");
114
+ plot.setRangeAxis(valueAxis0);
115
+
116
+ plot.setRenderer(0, renderer0);
117
+ plot.setDataset(0, createDataset0(dname, xi));
118
+
119
+ plot.setRenderer(1, renderer1);
120
+ plot.setDataset(1, createDataset1());
121
+
122
+ return plot;
123
+ }
124
+ private XYSeriesCollection createDataset0(String dname, double[] xi) {
125
+ double den = sd / Math.sqrt(xi.length);
126
+ XYSeries series = new XYSeries(dname);
127
+
128
+ for (int i = 0; i < xi.length; i++) {
129
+ double x = (xi[i] - m) / den;
130
+
131
+ series.add(x, xi[i]);
132
+ }
133
+ XYSeriesCollection data = new XYSeriesCollection();
134
+
135
+ data.addSeries(series);
136
+ return data;
137
+ }
138
+ private XYSeriesCollection createDataset1() {
139
+ XYSeries series = new XYSeries("累積");
140
+ NormalDistribution ndist = new NormalDistribution(0, 1);
141
+
142
+ for (double p = 0.001; p < 1.0; p += 0.01) {
143
+ double x = ndist.inverseCumulativeProbability(p);
144
+
145
+ series.add(x, x * sd + m);
146
+ }
147
+
148
+ XYSeriesCollection data = new XYSeriesCollection();
149
+ data.addSeries(series);
150
+ return data;
151
+ }
152
+ }
153
+ // コルモゴルフ・スミルノフ検定
154
+ private static class KSTest implements ChartPlot {
155
+ private NormalDistribution ndist = null;
156
+ public KSTest() {
157
+ ndist = new NormalDistribution(0, 1);
158
+ }
159
+ public JFreeChart createChart(String dname, double[] xi) {
160
+ NumberAxis domainAxis = new NumberAxis("標準正規分布");
161
+ XYPlot plot = createPlot(dname, xi);
162
+
163
+ /*--- 横軸 ---*/
164
+ plot.setDomainAxis(domainAxis);
165
+ domainAxis.setLowerMargin(0.03);
166
+ domainAxis.setUpperMargin(0.03);
167
+ domainAxis.setLowerBound(-4);
168
+ domainAxis.setUpperBound(4);
169
+
170
+ ChartFactory.setChartTheme(StandardChartTheme.createLegacyTheme());
171
+ return new JFreeChart("コルモゴルフ・スミルノフ検定", plot);
172
+ }
173
+ private XYPlot createPlot(String dname, double[] xi) {
174
+ XYItemRenderer renderer0 = new XYLineAndShapeRenderer(false, true);
175
+ XYItemRenderer renderer1 = new XYLineAndShapeRenderer(true, false);
176
+ XYToolTipGenerator toolTipGenerator = new StandardXYToolTipGenerator();
177
+
178
+ renderer0.setDefaultToolTipGenerator(toolTipGenerator);
179
+ renderer0.setURLGenerator(null);
180
+ renderer1.setDefaultToolTipGenerator(toolTipGenerator);
181
+ renderer1.setURLGenerator(null);
182
+
183
+ XYPlot plot = new XYPlot();
184
+ plot.setOrientation(PlotOrientation.VERTICAL);
185
+ plot.mapDatasetToRangeAxis(0,0);
186
+ plot.mapDatasetToRangeAxis(1,0);
187
+ plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
188
+
189
+ /*--- 縦軸 ---*/
190
+ NumberAxis valueAxis0 = new NumberAxis("確率");
191
+ plot.setRangeAxis(valueAxis0);
192
+ valueAxis0.setLowerBound(0);
193
+ valueAxis0.setUpperBound(1);
194
+ valueAxis0.setTickUnit(new NumberTickUnit(0.1));
195
+ valueAxis0.setNumberFormatOverride(new DecimalFormat("0.0#"));
196
+
197
+ plot.setRenderer(0, renderer0);
198
+ plot.setDataset(0, createDataset0(dname, xi));
199
+
200
+ plot.setRenderer(1, renderer1);
201
+ plot.setDataset(1, createDataset1());
202
+
203
+ return plot;
204
+ }
205
+ private XYSeriesCollection createDataset0(String dname, double[] xi) {
206
+ Arrays.sort(xi);
207
+ DescriptiveStatistics stat = new DescriptiveStatistics();
208
+ Arrays.stream(xi).forEach(stat::addValue);
209
+ double m = stat.getMean(); // 平均
210
+ double sd = stat.getStandardDeviation();// 標準偏差
211
+ double den = sd / Math.sqrt(xi.length);
212
+ double sum = stat.getSum();
213
+ double p = 0.0;
214
+
215
+ XYSeries series = new XYSeries(dname);
216
+ for (int n = 0; n < xi.length; n++) {
217
+ double x = (xi[n] - m) / den;
218
+
219
+ p += xi[n] / sum;
220
+ series.add(x, p);
221
+ }
222
+ XYSeriesCollection data = new XYSeriesCollection();
223
+
224
+ data.addSeries(series);
225
+ return data;
226
+ }
227
+ private XYSeriesCollection createDataset1() {
228
+ XYSeries series = new XYSeries("累積");
229
+
230
+ for (double x = -4; x < 4; x += 0.01) {
231
+ double y = ndist.cumulativeProbability(x);
232
+
233
+ series.add(x, y);
234
+ }
235
+ XYSeriesCollection data = new XYSeriesCollection();
236
+
237
+ data.addSeries(series);
238
+ return data;
239
+ }
240
+ }
241
+ // タコスディーノ検定(歪度)
242
+ private static class SkewnessTest implements DAgostinosTest {
243
+ private long n = 0;
244
+ private NormalDistribution ndist = null;
245
+ public SkewnessTest() {
246
+ ndist = new NormalDistribution(0, 1);
247
+ }
248
+ public double calcTestStatistic(double[] xi) {
249
+ DescriptiveStatistics stat = new DescriptiveStatistics();
250
+
251
+ Arrays.stream(xi).forEach(stat::addValue);
252
+ n = stat.getN();
253
+ return Math.sqrt(stat.getSkewness());
254
+ }
255
+
256
+ public boolean test(double statistic, double a) {
257
+ double ua_2 = ndist.inverseCumulativeProbability(1.0 - a);
258
+
259
+ return (Math.abs(statistic) > cnvb2tob2p(ua_2))
260
+ ? true : false;
261
+ }
262
+ private double cnvb2tob2p(double ua_2) {
263
+ double el = (n + 1.0) * (n + 1.0) * (n + 3.0) * (n + 5.0); // 分子
264
+ double den = 24 * n * (n - 2.0) * (n - 3.0); // 分母
265
+ double b2p = Math.sqrt(el / den) *
266
+ (long)(ua_2 + 3.0 / (2.0 * n) * (ua_2 * ua_2 * ua_2 - 3 * ua_2));
267
+
268
+ return b2p;
269
+ }
270
+ }
271
+ // タコスディーノ検定(尖度)
272
+ private static class KurtosisTest implements DAgostinosTest {
273
+ private long n = 0;
274
+ private NormalDistribution ndist = null;
275
+ public KurtosisTest() {
276
+ ndist = new NormalDistribution(0, 1);
277
+ }
278
+ public double calcTestStatistic(double[] xi) {
279
+ DescriptiveStatistics stat = new DescriptiveStatistics();
280
+
281
+ Arrays.stream(xi).forEach(stat::addValue);
282
+ n = stat.getN();
283
+
284
+ return stat.getKurtosis();
285
+ }
286
+ public boolean test(double statistic, double a) {
287
+ boolean ret = false;
288
+ double ua_2 = ndist.inverseCumulativeProbability(1.0 - a);
289
+ double b2p = cnvb2tob2p(statistic);
290
+
291
+ double r_val = ua_2 + Math.sqrt(6.0 / n) * (ua_2 * ua_2 - 1.0);
292
+ double l_val = -1.0 * ua_2 + Math.sqrt(6.0 / n) * (ua_2 * ua_2 - 1.0);
293
+
294
+ if (b2p > r_val) {
295
+ ret = true;
296
+ }
297
+ if (b2p < l_val) {
298
+ ret = true;
299
+ }
300
+ return ret;
301
+ }
302
+ private double cnvb2tob2p(double b2) {
303
+ double el = (n + 1.0) * (n + 1.0) * (n + 3.0) * (n + 5.0); // 分子
304
+ double den = 24 * n * (n - 2.0) * (n - 3.0); // 分母
305
+
306
+ double b2p = Math.sqrt(el / den) *
307
+ (long)(b2 - 3 * (n - 1.0) / (n + 3.0));
308
+
309
+ return b2p;
310
+ }
311
+ }
312
+ }
313
+
Binary file
Binary file
Binary file
@@ -0,0 +1,68 @@
1
+ require 'java'
2
+ require 'num4normality.jar'
3
+ require 'jfreechart-1.5.4.jar'
4
+ require 'commons-math3-3.6.1.jar'
5
+
6
+ java_import 'Normality'
7
+
8
+ # 正規性の検定
9
+ # (Apache commoms math3使用)
10
+ module Num4NormalityLib
11
+ class << self
12
+ # Q-Qプロット
13
+ #
14
+ # @overload qqplot(dname, xi)
15
+ # @param [String] dname データ名
16
+ # @param [Array] xi データ(double[])
17
+ # @return [void] qqplot.jpegファイルを出力
18
+ # @example
19
+ # xi = [320, 240, 402, 325, 440, 286, 362, 281, 560, 212, 198, 209]
20
+ # Num4NormalityLib.qqplot("LDH", xi)
21
+ # => qqplot.jpeg
22
+ # @note
23
+ # グラフは、jfreechartを使用
24
+ def qqplot(dname, xi)
25
+ Normality.qqplot(dname, xi.to_java(Java::double))
26
+ end
27
+ # コルモゴルフ・スミルノフ検定
28
+ #
29
+ # @overload kstest(dname, xi)
30
+ # @param [String] dname データ名
31
+ # @param [Array] xi データ(double[])
32
+ # @return [void] kstest.jpegファイルを出力
33
+ # @example
34
+ # xi = [320, 240, 402, 325, 440, 286, 362, 281, 560, 212, 198, 209]
35
+ # Num4NormalityLib.kstest("LDH", xi)
36
+ # => kstest.jpeg
37
+ # @note
38
+ # グラフは、jfreechartを使用
39
+ def kstest(dname, xi)
40
+ Normality.kstest(dname, xi.to_java(Java::double))
41
+ end
42
+ # タコスディーノ検定(歪度)
43
+ #
44
+ # @overload skewnesstest(xi)
45
+ # @param [Array] xi データ(double[])
46
+ # @return [boolean] 検定結果(true:棄却域内 false:棄却域外)
47
+ # @example
48
+ # xi = [320, 240, 402, 325, 440, 286, 362, 281, 560, 212, 198, 209]
49
+ # Num4NormalityLib.skewnesstest(xi)
50
+ # => false
51
+ def skewnesstest(xi)
52
+ Normality.skewnesstest(xi.to_java(Java::double))
53
+ end
54
+ # タコスディーノ検定(尖度)
55
+ #
56
+ # @overload kurtosistest(xi)
57
+ # @param [Array] xi データ(double[])
58
+ # @return [boolean] 検定結果(true:棄却域内 false:棄却域外)
59
+ # @example
60
+ # xi = [320, 240, 402, 325, 440, 286, 362, 281, 560, 212, 198, 209]
61
+ # Num4NormalityLib.kurtosistest(xi)
62
+ # => false
63
+ def kurtosistest(xi)
64
+ Normality.kurtosistest(xi.to_java(Java::double))
65
+ end
66
+ end
67
+ end
68
+
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: num4normality
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: 2023-12-05 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 test of normality.
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/num4normality/Normality.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/num4normality.rb
69
+ homepage: http://github.com/siranovel/num4normality
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 normality
92
+ test_files: []