From ca306ea40e30e7a9376318c07505a458c8e754cb Mon Sep 17 00:00:00 2001 From: Alexander Herzog Date: Sat, 5 Oct 2024 00:51:31 +0200 Subject: [PATCH] SimSystem and SimTools update --- SimSystem/.classpath | 1 - SimSystem/pom.xml | 20 +- .../src/main/java/mathtools/NumberTools.java | 15 +- .../distribution/ArcsineDistribution.java | 137 + .../distribution/DataDistributionImpl.java | 8 +- ...reteNegativeHyperGeomDistributionImpl.java | 141 + .../DiscretePoissonDistributionImpl.java | 20 +- .../distribution/HalfNormalDistribution.java | 2 +- .../distribution/IrwinHallDistribution.java | 146 + .../distribution/KumaraswamyDistribution.java | 170 ++ .../distribution/LevyDistribution.java | 12 +- .../LogLogisticDistributionImpl.java | 1 + .../MaxwellBoltzmannDistribution.java | 16 +- .../distribution/ParetoDistributionImpl.java | 8 + .../distribution/ReciprocalDistribution.java | 146 + .../distribution/SineDistribution.java | 150 + .../distribution/UQuadraticDistribution.java | 174 ++ .../distribution/swing/JDataLoader.java | 6 +- .../swing/JDistributionEditorPanelRecord.java | 269 +- .../swing/JDistributionPanel.java | 48 +- .../swing/SimSystemsSwingImages.java | 5 +- .../mathtools/distribution/swing/res/fx.png | Bin 0 -> 26467 bytes .../mathtools/distribution/swing/res24/fx.png | Bin 0 -> 26767 bytes .../mathtools/distribution/swing/res32/fx.png | Bin 0 -> 27180 bytes .../mathtools/distribution/swing/res48/fx.png | Bin 0 -> 27880 bytes .../tools/AbstractDistributionWrapper.java | 85 + .../tools/DistributionFitterBase.java | 6 +- .../distribution/tools/DistributionTools.java | 62 +- .../tools/WrapperArcsineDistribution.java | 152 + .../tools/WrapperBetaDistribution.java | 10 + .../tools/WrapperBinomialDistribution.java | 12 + .../tools/WrapperCauchyDistribution.java | 7 + .../tools/WrapperChiDistribution.java | 7 + .../tools/WrapperChiSquaredDistribution.java | 7 + .../tools/WrapperDataDistribution.java | 19 + .../WrapperDiscreteUniformDistribution.java | 7 + .../tools/WrapperErlangDistribution.java | 13 + .../tools/WrapperExponentialDistribution.java | 7 + .../tools/WrapperFDistribution.java | 7 + .../tools/WrapperFatigueLifeDistribution.java | 7 + .../tools/WrapperFrechetDistribution.java | 7 + .../tools/WrapperGammaDistribution.java | 16 + .../tools/WrapperGumbelDistribution.java | 16 + .../tools/WrapperHalfNormalDistribution.java | 7 + .../tools/WrapperHyperGeomDistribution.java | 7 + .../WrapperHyperbolicSecantDistribution.java | 7 + .../WrapperInverseGaussianDistribution.java | 7 + .../tools/WrapperIrwinHallDistribution.java | 146 + .../tools/WrapperJohnsonDistribution.java | 7 + .../tools/WrapperKumaraswamyDistribution.java | 148 + .../tools/WrapperLaplaceDistribution.java | 7 + .../tools/WrapperLevyDistribution.java | 11 +- .../tools/WrapperLogLogisticDistribution.java | 28 + .../tools/WrapperLogNormalDistribution.java | 7 + .../tools/WrapperLogisticDistribution.java | 7 + .../WrapperMaxwellBoltzmannDistribution.java | 7 + .../WrapperNegativeBinomialDistribution.java | 12 + .../WrapperNegativeHyperGeomDistribution.java | 129 + .../tools/WrapperNormalDistribution.java | 7 + .../tools/WrapperOnePointDistribution.java | 5 + .../tools/WrapperParetoDistribution.java | 7 + .../tools/WrapperPertDistribution.java | 7 + .../tools/WrapperPoissonDistribution.java | 7 + .../tools/WrapperPowerDistribution.java | 7 + .../tools/WrapperRayleighDistribution.java | 7 + .../tools/WrapperReciprocalDistribution.java | 137 + .../WrapperSawtoothLeftDistribution.java | 7 + .../WrapperSawtoothRightDistribution.java | 7 + .../tools/WrapperSineDistribution.java | 152 + .../tools/WrapperStudentTDistribution.java | 7 + .../tools/WrapperTrapezoidDistribution.java | 7 + .../tools/WrapperTriangularDistribution.java | 7 + .../tools/WrapperUQuadraticDistribution.java | 161 ++ .../tools/WrapperUniformRealDistribution.java | 7 + .../tools/WrapperWeibullDistribution.java | 7 + .../tools/WrapperZetaDistribution.java | 7 + .../distribution/tools/res/arcsine.png | Bin 0 -> 28633 bytes .../mathtools/distribution/tools/res/chi.png | Bin 25956 -> 28470 bytes .../distribution/tools/res/chisquare.png | Bin 26744 -> 27689 bytes .../distribution/tools/res/reciprocal.png | Bin 0 -> 29341 bytes .../mathtools/distribution/tools/res/sine.png | Bin 0 -> 29183 bytes .../distribution/tools/res/uquadratic.png | Bin 0 -> 28922 bytes .../src/main/java/parser/CalcSymbolList.java | 20 + .../parser/symbols/CalcSymbolConstTau.java | 44 + .../CalcSymbolDiscreteDistribution.java | 11 +- ...alcSymbolDiscreteDistributionBinomial.java | 2 +- ...lcSymbolDiscreteDistributionHyperGeom.java | 2 +- ...lDiscreteDistributionNegativeBinomial.java | 2 +- ...eteDistributionNegativeBinomialDirect.java | 2 +- ...DiscreteDistributionNegativeHyperGeom.java | 71 + ...CalcSymbolDiscreteDistributionPoisson.java | 20 +- ...CalcSymbolDiscreteDistributionUniform.java | 2 +- .../CalcSymbolDiscreteDistributionZeta.java | 2 +- .../distributions/CalcSymbolDistribution.java | 2 +- .../CalcSymbolDistributionArcsine.java | 58 + .../CalcSymbolDistributionBeta.java | 2 +- .../CalcSymbolDistributionCauchy.java | 2 +- .../CalcSymbolDistributionChi.java | 2 +- .../CalcSymbolDistributionChiSquare.java | 2 +- .../CalcSymbolDistributionExp.java | 2 +- .../CalcSymbolDistributionF.java | 2 +- .../CalcSymbolDistributionFatigueLife.java | 2 +- .../CalcSymbolDistributionFrechet.java | 2 +- .../CalcSymbolDistributionGamma.java | 2 +- .../CalcSymbolDistributionGammaDirect.java | 2 +- .../CalcSymbolDistributionGumbel.java | 2 +- .../CalcSymbolDistributionGumbelDirect.java | 72 + .../CalcSymbolDistributionHalfNormal.java | 2 +- ...alcSymbolDistributionHyperbolicSecant.java | 2 +- ...CalcSymbolDistributionInverseGaussian.java | 2 +- .../CalcSymbolDistributionIrwinHall.java | 58 + ...CalcSymbolDistributionIrwinHallDirect.java | 59 + .../CalcSymbolDistributionJohnsonSU.java | 2 +- .../CalcSymbolDistributionKumaraswamy.java | 59 + .../CalcSymbolDistributionLaplace.java | 2 +- .../CalcSymbolDistributionLevy.java | 2 +- .../CalcSymbolDistributionLogLogistic.java | 2 +- .../CalcSymbolDistributionLogNormal.java | 2 +- .../CalcSymbolDistributionLogistic.java | 2 +- ...alcSymbolDistributionMaxwellBoltzmann.java | 2 +- .../CalcSymbolDistributionNormal.java | 2 +- .../CalcSymbolDistributionPareto.java | 2 +- .../CalcSymbolDistributionPert.java | 2 +- .../CalcSymbolDistributionPower.java | 2 +- .../CalcSymbolDistributionRayleigh.java | 2 +- .../CalcSymbolDistributionReciprocal.java | 58 + .../CalcSymbolDistributionSawtoothLeft.java | 2 +- .../CalcSymbolDistributionSawtoothRight.java | 2 +- .../CalcSymbolDistributionSine.java | 58 + .../CalcSymbolDistributionStudentT.java | 2 +- .../CalcSymbolDistributionTrapezoid.java | 2 +- .../CalcSymbolDistributionTriangular.java | 2 +- .../CalcSymbolDistributionUQuadratic.java | 58 + .../CalcSymbolDistributionUniform.java | 2 +- .../CalcSymbolDistributionWeibull.java | 2 +- ...CalcSymbolEmpiricalDistributionRandom.java | 2 +- .../java/simcore/logging/PlainTextLogger.java | 2 +- .../main/java/statistics/StatisticsBase.java | 20 +- .../StatisticsDataPerformanceIndicator.java | 52 +- ...erformanceIndicatorWithNegativeValues.java | 52 +- .../StatisticsMultiPerformanceIndicator.java | 36 +- ...icsTimeContinuousPerformanceIndicator.java | 14 +- .../StatisticsTimePerformanceIndicator.java | 18 +- .../DataDistributionImplTest.java | 2 +- .../DistributionFitterTest.java | 3 - .../distributiontests/DistributionTests.java | 621 +++++ .../DistributionToolsTests.java | 12 + .../test/java/parsertests/SymbolsTests.java | 2437 ++++++----------- SimTools/.classpath | 7 +- SimTools/pom.xml | 8 +- .../main/java/systemtools/AlphaButton.java | 154 ++ .../src/main/java/systemtools/BaseDialog.java | 186 +- .../main/java/systemtools/ColorChooser.java | 90 + .../java/systemtools/ColorChooserButton.java | 183 ++ .../java/systemtools/JScrollPaneTouch.java | 89 + .../systemtools/JScrollPaneTouchHelper.java | 96 + .../java/systemtools/LabeledAlphaButton.java | 122 + .../LabeledColorChooserButton.java | 101 + .../OptionalColorChooserButton.java | 136 + .../src/main/java/systemtools/SetupBase.java | 4 +- .../java/systemtools/SmallColorChooser.java | 47 +- .../commandline/CommandLineDialog.java | 3 + .../systemtools/help/HTMLBrowserTextPane.java | 5 +- .../main/java/systemtools/help/HTMLPanel.java | 172 +- .../help/HTMLPanelSearchDialog.java | 88 +- .../help/HTMLPanelSelectDialog.java | 4 +- .../main/java/systemtools/help/HelpBase.java | 4 + .../java/systemtools/help/IndexScanner.java | 16 + .../java/systemtools/help/IndexSystem.java | 23 + .../systemtools/images/SimToolsImages.java | 6 + .../images/res/table_lightning.png | Bin 0 -> 736 bytes .../images/res/table_row_insert.png | Bin 0 -> 641 bytes .../images/res24/table-lightning.png | Bin 0 -> 1161 bytes .../images/res24/table-row-insert.png | Bin 0 -> 981 bytes .../images/res32/table-lightning.png | Bin 0 -> 1268 bytes .../images/res32/table-row-insert.png | Bin 0 -> 996 bytes .../images/res48/table-lightning.png | Bin 0 -> 1937 bytes .../images/res48/table-row-insert.png | Bin 0 -> 1307 bytes .../statistics/ChartSetupDialog.java | 62 +- .../systemtools/statistics/PDFWriterBase.java | 211 ++ .../statistics/StatisticViewerTable.java | 84 +- ...tatisticViewerTableColumnSelectDialog.java | 92 + .../StatisticViewerTableFilterDialog.java | 84 +- .../statistics/StatisticViewerText.java | 63 + .../statistics/StatisticsBasePanel.java | 8 + Simulator/.classpath | 7 +- Simulator/language/gettext_de.mo | Bin 411194 -> 412635 bytes Simulator/language/gettext_de.po | 59 +- Simulator/language/gettext_en.mo | Bin 390794 -> 392240 bytes Simulator/language/gettext_en.po | 59 +- .../java/language/LanguageStaticLoader.java | 19 + .../src/main/java/language/Messages_de.java | 102 +- .../src/main/java/language/Messages_en.java | 102 +- Simulator/src/main/java/ui/MainPanel.java | 3 +- .../main/java/ui/help/pages_de/Changelog.html | 5 + .../main/java/ui/help/pages_en/Changelog.html | 5 + 196 files changed, 7304 insertions(+), 2234 deletions(-) create mode 100644 SimSystem/src/main/java/mathtools/distribution/ArcsineDistribution.java create mode 100644 SimSystem/src/main/java/mathtools/distribution/DiscreteNegativeHyperGeomDistributionImpl.java create mode 100644 SimSystem/src/main/java/mathtools/distribution/IrwinHallDistribution.java create mode 100644 SimSystem/src/main/java/mathtools/distribution/KumaraswamyDistribution.java create mode 100644 SimSystem/src/main/java/mathtools/distribution/ReciprocalDistribution.java create mode 100644 SimSystem/src/main/java/mathtools/distribution/SineDistribution.java create mode 100644 SimSystem/src/main/java/mathtools/distribution/UQuadraticDistribution.java create mode 100644 SimSystem/src/main/java/mathtools/distribution/swing/res/fx.png create mode 100644 SimSystem/src/main/java/mathtools/distribution/swing/res24/fx.png create mode 100644 SimSystem/src/main/java/mathtools/distribution/swing/res32/fx.png create mode 100644 SimSystem/src/main/java/mathtools/distribution/swing/res48/fx.png create mode 100644 SimSystem/src/main/java/mathtools/distribution/tools/WrapperArcsineDistribution.java create mode 100644 SimSystem/src/main/java/mathtools/distribution/tools/WrapperIrwinHallDistribution.java create mode 100644 SimSystem/src/main/java/mathtools/distribution/tools/WrapperKumaraswamyDistribution.java create mode 100644 SimSystem/src/main/java/mathtools/distribution/tools/WrapperNegativeHyperGeomDistribution.java create mode 100644 SimSystem/src/main/java/mathtools/distribution/tools/WrapperReciprocalDistribution.java create mode 100644 SimSystem/src/main/java/mathtools/distribution/tools/WrapperSineDistribution.java create mode 100644 SimSystem/src/main/java/mathtools/distribution/tools/WrapperUQuadraticDistribution.java create mode 100644 SimSystem/src/main/java/mathtools/distribution/tools/res/arcsine.png create mode 100644 SimSystem/src/main/java/mathtools/distribution/tools/res/reciprocal.png create mode 100644 SimSystem/src/main/java/mathtools/distribution/tools/res/sine.png create mode 100644 SimSystem/src/main/java/mathtools/distribution/tools/res/uquadratic.png create mode 100644 SimSystem/src/main/java/parser/symbols/CalcSymbolConstTau.java create mode 100644 SimSystem/src/main/java/parser/symbols/distributions/CalcSymbolDiscreteDistributionNegativeHyperGeom.java create mode 100644 SimSystem/src/main/java/parser/symbols/distributions/CalcSymbolDistributionArcsine.java create mode 100644 SimSystem/src/main/java/parser/symbols/distributions/CalcSymbolDistributionGumbelDirect.java create mode 100644 SimSystem/src/main/java/parser/symbols/distributions/CalcSymbolDistributionIrwinHall.java create mode 100644 SimSystem/src/main/java/parser/symbols/distributions/CalcSymbolDistributionIrwinHallDirect.java create mode 100644 SimSystem/src/main/java/parser/symbols/distributions/CalcSymbolDistributionKumaraswamy.java create mode 100644 SimSystem/src/main/java/parser/symbols/distributions/CalcSymbolDistributionReciprocal.java create mode 100644 SimSystem/src/main/java/parser/symbols/distributions/CalcSymbolDistributionSine.java create mode 100644 SimSystem/src/main/java/parser/symbols/distributions/CalcSymbolDistributionUQuadratic.java create mode 100644 SimTools/src/main/java/systemtools/AlphaButton.java create mode 100644 SimTools/src/main/java/systemtools/ColorChooser.java create mode 100644 SimTools/src/main/java/systemtools/ColorChooserButton.java create mode 100644 SimTools/src/main/java/systemtools/JScrollPaneTouch.java create mode 100644 SimTools/src/main/java/systemtools/JScrollPaneTouchHelper.java create mode 100644 SimTools/src/main/java/systemtools/LabeledAlphaButton.java create mode 100644 SimTools/src/main/java/systemtools/LabeledColorChooserButton.java create mode 100644 SimTools/src/main/java/systemtools/OptionalColorChooserButton.java create mode 100644 SimTools/src/main/java/systemtools/images/res/table_lightning.png create mode 100644 SimTools/src/main/java/systemtools/images/res/table_row_insert.png create mode 100644 SimTools/src/main/java/systemtools/images/res24/table-lightning.png create mode 100644 SimTools/src/main/java/systemtools/images/res24/table-row-insert.png create mode 100644 SimTools/src/main/java/systemtools/images/res32/table-lightning.png create mode 100644 SimTools/src/main/java/systemtools/images/res32/table-row-insert.png create mode 100644 SimTools/src/main/java/systemtools/images/res48/table-lightning.png create mode 100644 SimTools/src/main/java/systemtools/images/res48/table-row-insert.png create mode 100644 SimTools/src/main/java/systemtools/statistics/StatisticViewerTableColumnSelectDialog.java diff --git a/SimSystem/.classpath b/SimSystem/.classpath index cd6ead0..12a3d91 100644 --- a/SimSystem/.classpath +++ b/SimSystem/.classpath @@ -3,7 +3,6 @@ - diff --git a/SimSystem/pom.xml b/SimSystem/pom.xml index 8cbcb0e..a43f181 100644 --- a/SimSystem/pom.xml +++ b/SimSystem/pom.xml @@ -27,7 +27,7 @@ org.xerial sqlite-jdbc - 3.45.2.0 + 3.46.1.0 @@ -39,13 +39,13 @@ commons-io commons-io - 2.15.1 + 2.16.1 org.apache.poi poi - 5.2.5 + 5.3.0 @@ -63,20 +63,20 @@ org.apache.logging.log4j log4j-core - 2.21.1 + 2.23.1 org.junit.jupiter junit-jupiter-api - 5.10.2 + 5.11.0 test org.junit.jupiter junit-jupiter-engine - 5.10.2 + 5.11.0 test @@ -84,7 +84,7 @@ org.slf4j slf4j-simple - 2.0.12 + 2.0.16 test --> @@ -92,13 +92,13 @@ org.slf4j slf4j-api - 2.0.12 + 2.0.16 org.slf4j slf4j-nop - 2.0.12 + 2.0.16 @@ -123,7 +123,7 @@ org.apache.jena jena-core - 4.10.0 + 5.1.0 diff --git a/SimSystem/src/main/java/mathtools/NumberTools.java b/SimSystem/src/main/java/mathtools/NumberTools.java index bbf9de9..32b0830 100644 --- a/SimSystem/src/main/java/mathtools/NumberTools.java +++ b/SimSystem/src/main/java/mathtools/NumberTools.java @@ -34,7 +34,7 @@ * Enthält einige statische Routinen zur Umwandlung von Zeichenketten in Zahlen * und umgekehrt. * @author Alexander Herzog - * @version 2.7 + * @version 2.8 */ public final class NumberTools { /** String, der "0" enthält (um diesen nicht mehrfach anlegen zu müssen) */ @@ -1214,17 +1214,26 @@ public static Double getDouble(final String s) { boolean isPlain=true; boolean hasDecimal=false; + boolean needDecialReplace=false; final int len=s.length(); for (int i=0;i='0' && c<='9') continue; if (c=='-' && i>0) {isPlain=false; break;} - if ((c=='.' || c==',') && !hasDecimal) hasDecimal=true; else {isPlain=false; break;} + if ((c=='.' || c==',') && !hasDecimal) { + hasDecimal=true; + if (c==',') needDecialReplace=true; + } + else {isPlain=false; break;} } if (isPlain) { if (hasDecimal) { try { - return fastBoxedValue(Double.parseDouble(s)); + if (needDecialReplace) { + return fastBoxedValue(Double.parseDouble(s.replace(',','.'))); + } else { + return fastBoxedValue(Double.parseDouble(s)); + } } catch (NumberFormatException e) {/* bei zu großen Zahlen: Fallback auf Double-Parser, der kommt damit klar */} } else { try { diff --git a/SimSystem/src/main/java/mathtools/distribution/ArcsineDistribution.java b/SimSystem/src/main/java/mathtools/distribution/ArcsineDistribution.java new file mode 100644 index 0000000..fe6a1f1 --- /dev/null +++ b/SimSystem/src/main/java/mathtools/distribution/ArcsineDistribution.java @@ -0,0 +1,137 @@ +/** + * Copyright 2024 Alexander Herzog + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package mathtools.distribution; + +import java.io.Serializable; + +import org.apache.commons.math3.distribution.AbstractRealDistribution; +import org.apache.commons.math3.exception.OutOfRangeException; +import org.apache.commons.math3.random.RandomGenerator; + +/** + * Klasse zur Abbildung der Arcus Sinus-Verteilung
+ * Siehe auch: http://www.randomservices.org/random/special/Arcsine.html + * @author Alexander Herzog + */ +public class ArcsineDistribution extends AbstractRealDistribution implements Cloneable, Serializable, DistributionWithRandom { + /** + * Serialisierungs-ID der Klasse + * @see Serializable + */ + private static final long serialVersionUID=6569135516191696579L; + + /** + * Untere Grenze des Trägers + */ + public final double a; + + /** + * Obere Grenze des Trägers + */ + public final double b; + + /** + * Konstruktor + * @param a Untere Grenze des Trägers + * @param b Obere Grenze des Trägers + */ + public ArcsineDistribution(final double a, final double b) { + super(null); + this.a=a; + this.b=Math.max(a+0.0001,b); + } + + /** + * Copy-Konstruktor + * @param source Zu kopierende Ausgangsverteilung + */ + public ArcsineDistribution(final ArcsineDistribution source) { + this((source==null)?0:source.a,(source==null)?10:source.b); + } + + @Override + public double density(double x) { + if (x<=a || x>=b) return 0; + x=(x-a)/(b-a); + return 1.0/Math.PI/Math.sqrt(x*(1-x)); + } + + @Override + public double cumulativeProbability(double x) { + if (x<=a) return 0; + if (x>=b) return 1; + x=(x-a)/(b-a); + + return 2.0/Math.PI*Math.asin(Math.sqrt(x)); + } + + @Override + public ArcsineDistribution clone() { + return new ArcsineDistribution(a,b); + } + + @Override + public double getNumericalMean() { + return (a+b)/2.0; + } + + @Override + public double getNumericalVariance() { + return 1.0/8.0*(b-a)*(b-a); + } + + @Override + public double getSupportLowerBound() { + return a; + } + + @Override + public double getSupportUpperBound() { + return b; + } + + @Override + public boolean isSupportLowerBoundInclusive() { + return true; + } + + @Override + public boolean isSupportUpperBoundInclusive() { + return true; + } + + @Override + public boolean isSupportConnected() { + return true; + } + + @Override + public double inverseCumulativeProbability(final double p) throws OutOfRangeException { + if (p<0.0 || p>1.0) throw new OutOfRangeException(p,0,1); + + if (p==0.0) return getSupportLowerBound(); + if (p==1.0) return getSupportUpperBound(); + + /* p=2/pi*arcsin(sqrt(x)) <=> x=(sin(pi/2*p))^2 */ + final double z=Math.pow(Math.sin(Math.PI/2.0*p),2); + return z*(b-a)+a; + } + + @Override + public double random(final RandomGenerator generator) { + return inverseCumulativeProbability(generator.nextDouble()); + } +} diff --git a/SimSystem/src/main/java/mathtools/distribution/DataDistributionImpl.java b/SimSystem/src/main/java/mathtools/distribution/DataDistributionImpl.java index 8bd2a48..98c50e3 100644 --- a/SimSystem/src/main/java/mathtools/distribution/DataDistributionImpl.java +++ b/SimSystem/src/main/java/mathtools/distribution/DataDistributionImpl.java @@ -669,7 +669,7 @@ public double inverseCumulativeProbabilityWithOutThrowsAndChecks(double p) { */ @Override public double random(final RandomGenerator generator) { - /* return inverseCumulativeProbabilityWithOutThrowsAndChecks(rnd.nextDouble()); */ + /* return inverseCumulativeProbabilityWithOutThrowsAndChecks(generator.nextDouble()); */ double p=generator.nextDouble(); @@ -1057,7 +1057,7 @@ public double getMean() { double scale=1/argumentScaleFactor; for (int i=0;ihttps://de.wikipedia.org/wiki/Negative_hypergeometrische_Verteilung + * @author Alexander Herzog + * @see AbstractDiscreteRealDistribution + */ +public class DiscreteNegativeHyperGeomDistributionImpl extends AbstractDiscreteRealDistribution implements Cloneable, Serializable, DistributionWithRandom { + /** + * Serialisierungs-ID der Klasse + * @see Serializable + */ + private static final long serialVersionUID=-6390431157370879106L; + + + /** + * Gesamtanzahl an Kugeln in der Urne + */ + public final int N; + + /** + * Anzahl an roten Kugeln in der Urne + */ + public final int K; + + /** + * Anzahl der roten Kugeln, die ohne Zurücklegen gezogen werden sollen + */ + public final int n; + + /** + * Bereits im Konstruktor berechneter Nenner der Zähldichte + */ + private final double densityDenominator; + + /** + * Modus (wird initial auf -1 gesetzt und beim ersten Aufruf von {@link #getMode()} berechnet und dann hier gespeichert) + * @see #getMode() + */ + private int mode=-1; + + /** + * Konstruktor der Klasse + * @param N Gesamtanzahl an Kugeln in der Urne + * @param K Anzahl an roten Kugeln in der Urne + * @param n Anzahl der Kugeln, die der Urne entnommen werden + */ + public DiscreteNegativeHyperGeomDistributionImpl(final int N, final int K, final int n) { + this.N=Math.max(N,1); + this.K=Math.max(0,Math.min(N,K)); + this.n=Math.max(1,Math.min(K,n)); + densityDenominator=CalcSymbolPreOperatorBinomial.binomialCoefficient(N,K); + } + + /** + * Copy-Konstruktor + * @param source Zu kopierende Ausgangsverteilung + */ + public DiscreteNegativeHyperGeomDistributionImpl(final DiscreteNegativeHyperGeomDistributionImpl source) { + this((source==null)?1:source.N,(source==null)?1:source.K,(source==null)?1:source.n); + } + + @Override + protected double getCountDensity(int k) { + try { + return CalcSymbolPreOperatorBinomial.binomialCoefficient(k-1,n-1)*CalcSymbolPreOperatorBinomial.binomialCoefficient(N-k,K-n)/densityDenominator; + } catch (Exception e) { + return 0; + } + } + + @Override + public DiscreteNegativeHyperGeomDistributionImpl clone() { + return new DiscreteNegativeHyperGeomDistributionImpl(this); + } + + @Override + public double getNumericalMean() { + return n*((double)N+1)/((double)K+1); + } + + @Override + public double getNumericalVariance() { + return n*((double)K+1-n)*((double)N-K)*((double)N+1)/(((double)K+1)*((double)K+1)*((double)K+2)); + } + + /** + * Liefert den Modus der Verteilung. + * @return Modus der Verteilung + */ + public double getMode() { + if (mode>=0) return mode; + + int maxIndex=0; + double maxValue=getCountDensity(0); + + int index=1; + while (true) { + final double value=getCountDensity(index); + if (value>maxValue) { + maxValue=value; + maxIndex=index; + } else if (value - * https://mathworld.wolfram.com/Half-NormalDistribution.html + * https://mathworld.wolfram.com/Half-NormalDistribution.html * @author Alexander Herzog */ public final class HalfNormalDistribution extends AbstractRealDistribution implements Cloneable { diff --git a/SimSystem/src/main/java/mathtools/distribution/IrwinHallDistribution.java b/SimSystem/src/main/java/mathtools/distribution/IrwinHallDistribution.java new file mode 100644 index 0000000..7b634f2 --- /dev/null +++ b/SimSystem/src/main/java/mathtools/distribution/IrwinHallDistribution.java @@ -0,0 +1,146 @@ +/** + * Copyright 2024 Alexander Herzog + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package mathtools.distribution; + +import java.io.Serializable; + +import org.apache.commons.math3.distribution.AbstractRealDistribution; + +import mathtools.Functions; +import parser.symbols.CalcSymbolPreOperatorBinomial; + +/** + * Klasse zur Abbildung der Irwin-Hall-Verteilung + * @author Alexander Herzog + */ +public class IrwinHallDistribution extends AbstractRealDistribution implements Cloneable, Serializable { + /** + * Serialisierungs-ID der Klasse + * @see Serializable + */ + private static final long serialVersionUID=416452137962590289L; + + /** + * Parameter der Verteilung + */ + public final int n; + + /** + * Vorfaktor zur Berechnung der Dichte + * @see #density(double) + */ + private final double pdfFactor; + + /** + * Vorfaktor zur Berechnung der Verteilungsfunktion + * @see #cumulativeProbability(double) + */ + private final double cdfFactor; + + /** + * Konstruktor + * @param n Parameter + */ + public IrwinHallDistribution(final double n) { + super(null); + this.n=(int)Math.min(30,Math.max(1,Math.round(n))); + pdfFactor=1.0/Functions.getFactorial(this.n-1); + cdfFactor=1.0/Functions.getFactorial(this.n); + } + + /** + * Copy-Konstruktor + * @param source Zu kopierende Ausgangsverteilung + */ + public IrwinHallDistribution(final IrwinHallDistribution source) { + this((source==null)?1:source.n); + } + + @Override + public double density(double x) { + if (x<0 || x>n) return 0; + if (n>25) { + if (x>n*0.8) return 0; + } + double sum=0; + final int upperBound=(int)Math.floor(x); + for (int k=0;k<=upperBound;k++) { + double d=CalcSymbolPreOperatorBinomial.binomialCoefficient(n,k)*Math.pow(x-k,n-1); + if (k%2!=0) /* (k%2==1) wird von SpotBugs als Fehler gesehen, da dies für negatives k nicht funktioniert. - Auch wenn k hier überhaupt nicht negativ sein kann. */ + d=-d; + sum+=d; + } + return pdfFactor*sum; + } + + @Override + public double cumulativeProbability(double x) { + if (x<=0) return 0; + if (x>=n) return 1; + if (n>25) { + if (x>n*0.8) return 1; + } + double sum=0; + final int upperBound=(int)Math.floor(x); + for (int k=0;k<=upperBound;k++) { + double d=CalcSymbolPreOperatorBinomial.binomialCoefficient(n,k)*Math.pow(x-k,n); + if (k%2!=0) /* (k%2==1) wird von SpotBugs als Fehler gesehen, da dies für negatives k nicht funktioniert. - Auch wenn k hier überhaupt nicht negativ sein kann. */ + d=-d; + sum+=d; + } + return cdfFactor*sum; + } + + @Override + public IrwinHallDistribution clone() { + return new IrwinHallDistribution(n); + } + + @Override + public double getNumericalMean() { + return n/2.0; + } + + @Override + public double getNumericalVariance() { + return n/12.0; + } + + @Override + public double getSupportLowerBound() { + return 0; + } + + @Override + public double getSupportUpperBound() { + return n; + } + + @Override + public boolean isSupportLowerBoundInclusive() { + return true; + } + + @Override + public boolean isSupportUpperBoundInclusive() { + return true; + } + + @Override + public boolean isSupportConnected() { + return true; + } +} diff --git a/SimSystem/src/main/java/mathtools/distribution/KumaraswamyDistribution.java b/SimSystem/src/main/java/mathtools/distribution/KumaraswamyDistribution.java new file mode 100644 index 0000000..71e532e --- /dev/null +++ b/SimSystem/src/main/java/mathtools/distribution/KumaraswamyDistribution.java @@ -0,0 +1,170 @@ +/** + * Copyright 2024 Alexander Herzog + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package mathtools.distribution; + +import java.io.Serializable; + +import org.apache.commons.math3.distribution.AbstractRealDistribution; +import org.apache.commons.math3.exception.OutOfRangeException; +import org.apache.commons.math3.random.RandomGenerator; +import org.apache.commons.math3.special.Gamma; + +/** + * Klasse zur Abbildung der Kumaraswamy-Verteilung + * @author Alexander Herzog + */ +public class KumaraswamyDistribution extends AbstractRealDistribution implements Cloneable, Serializable, DistributionWithRandom { + /** + * Serialisierungs-ID der Klasse + * @see Serializable + */ + private static final long serialVersionUID=-5073494121705653463L; + + /** + * Parameter 1 + */ + public final double a; + + /** + * Parameter 2 + */ + public final double b; + + /** + * Untere Grenze des Trägers + */ + public final double c; + + /** + * Obere Grenze des Trägers + */ + public final double d; + + /** + * Vorab berechneter Erwartungswert + * @see #getNumericalMean() + */ + private final double mean; + + /** + * Vorab berechnete Varianz + * @see #getNumericalVariance() + */ + private final double variance; + + /** + * Konstruktor + * @param a Erster Parameter + * @param b Zweiter Parameter + * @param c Untere Grenze des Trägers + * @param d Obere Grenze des Trägers + */ + public KumaraswamyDistribution(final double a, final double b, final double c, final double d) { + super(null); + this.a=Math.max(0.0001,a); + this.b=Math.max(0.0001,b); + this.c=c; + this.d=Math.max(this.c+0.0001,d); + + final double m1=this.b*Gamma.gamma(1+1/this.a)*Gamma.gamma(this.b)/Gamma.gamma(1+1/this.a+this.b); + mean=m1*(this.d-this.c)+this.c; + final double m2=this.b*Gamma.gamma(1+2/this.a)*Gamma.gamma(this.b)/Gamma.gamma(1+2/this.a+this.b); + variance=(m2-m1*m1)*(this.d-this.c)*(this.d-this.c); + } + + /** + * Copy-Konstruktor + * @param source Zu kopierende Ausgangsverteilung + */ + public KumaraswamyDistribution(final KumaraswamyDistribution source) { + this((source==null)?0:source.a,(source==null)?10:source.b,(source==null)?0:source.c,(source==null)?10:source.d); + } + + @Override + public double density(double x) { + if (xd) return 0; + x=(x-c)/(d-c); + return a*b*Math.pow(x,a-1)*Math.pow(1-Math.pow(x,a),b-1); + } + + @Override + public double cumulativeProbability(double x) { + if (x<=c) return 0; + if (x>=d) return 1; + x=(x-c)/(d-c); + return 1-Math.pow(1-Math.pow(x,a),b); + } + + @Override + public KumaraswamyDistribution clone() { + return new KumaraswamyDistribution(a,b,c,d); + } + + @Override + public double getNumericalMean() { + return mean; + } + + @Override + public double getNumericalVariance() { + return variance; + } + + @Override + public double getSupportLowerBound() { + return c; + } + + @Override + public double getSupportUpperBound() { + return d; + } + + @Override + public boolean isSupportLowerBoundInclusive() { + return true; + } + + @Override + public boolean isSupportUpperBoundInclusive() { + return true; + } + + @Override + public boolean isSupportConnected() { + return true; + } + + @Override + public double inverseCumulativeProbability(final double p) throws OutOfRangeException { + if (p<0.0 || p>1.0) throw new OutOfRangeException(p,0,1); + + if (p==0.0) return getSupportLowerBound(); + if (p==1.0) return getSupportUpperBound(); + + /* + p=1-(1-x^a)^b + 1-x^a= + (1-(1-p)^(1/b))^(1/a)=x + */ + return Math.pow(1-Math.pow(1-p,1/b),1/a)*(d-c)+c; + } + + @Override + public double random(final RandomGenerator generator) { + return inverseCumulativeProbability(generator.nextDouble()); + } +} diff --git a/SimSystem/src/main/java/mathtools/distribution/LevyDistribution.java b/SimSystem/src/main/java/mathtools/distribution/LevyDistribution.java index cd5f89e..b7acd94 100644 --- a/SimSystem/src/main/java/mathtools/distribution/LevyDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/LevyDistribution.java @@ -69,15 +69,23 @@ public LevyDistribution(final double mu, final double c) { densityFactor=Math.sqrt(this.c/2/Math.PI); } + /** + * Copy-Konstruktor + * @param source Zu kopierende Ausgangsverteilung + */ + public LevyDistribution(final LevyDistribution source) { + this((source==null)?0:source.mu,(source==null)?1:source.c); + } + @Override public double density(double x) { - if (xb) return 0; + return 1/(x*logba); + } + + @Override + public double cumulativeProbability(double x) { + if (x<=a) return 0; + if (x>=b) return 1; + return Math.log(x/a)/logba; + } + + @Override + public ReciprocalDistribution clone() { + return new ReciprocalDistribution(a,b); + } + + @Override + public double getNumericalMean() { + return (b-a)/logba; + } + + @Override + public double getNumericalVariance() { + final double d=(b-a)/logba; + return (b*b-a*a)/(2*logba)-d*d; + } + + @Override + public double getSupportLowerBound() { + return a; + } + + @Override + public double getSupportUpperBound() { + return b; + } + + @Override + public boolean isSupportLowerBoundInclusive() { + return true; + } + + @Override + public boolean isSupportUpperBoundInclusive() { + return true; + } + + @Override + public boolean isSupportConnected() { + return true; + } + + @Override + public double inverseCumulativeProbability(final double p) throws OutOfRangeException { + if (p<0.0 || p>1.0) throw new OutOfRangeException(p,0,1); + + if (p==0.0) return getSupportLowerBound(); + if (p==1.0) return getSupportUpperBound(); + + /* + p=log(x/a)/logba + exp(p*logba)*a=x + */ + + return Math.exp(p*logba)*a; + } + + @Override + public double random(final RandomGenerator generator) { + return inverseCumulativeProbability(generator.nextDouble()); + } +} diff --git a/SimSystem/src/main/java/mathtools/distribution/SineDistribution.java b/SimSystem/src/main/java/mathtools/distribution/SineDistribution.java new file mode 100644 index 0000000..c40a1ba --- /dev/null +++ b/SimSystem/src/main/java/mathtools/distribution/SineDistribution.java @@ -0,0 +1,150 @@ +/** + * Copyright 2024 Alexander Herzog + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package mathtools.distribution; + +import java.io.Serializable; + +import org.apache.commons.math3.distribution.AbstractRealDistribution; +import org.apache.commons.math3.exception.OutOfRangeException; +import org.apache.commons.math3.random.RandomGenerator; + +/** + * Klasse zur Abbildung der Sinus-Verteilung
+ * Siehe auch: http://www.randomservices.org/random/special/Sine.html + * @author Alexander Herzog + */ +public class SineDistribution extends AbstractRealDistribution implements Cloneable, Serializable, DistributionWithRandom { + /** + * Serialisierungs-ID der Klasse + * @see Serializable + */ + private static final long serialVersionUID=5380306629461260392L; + + /** + * Untere Grenze des Trägers + */ + public final double a; + + /** + * Obere Grenze des Trägers + */ + public final double b; + + /** + * Vorabbrechnete Varianz + * @see #getNumericalVariance() + */ + private final double variance; + + /** + * Faktor zur schnelleren Berechnung der Dichte + * @see #density(double) + */ + private static final double pdfFactor=Math.PI/2.0; + + /** + * Konstruktor + * @param a Untere Grenze des Trägers + * @param b Obere Grenze des Trägers + */ + public SineDistribution(final double a, final double b) { + super(null); + this.a=a; + this.b=Math.max(a+0.0001,b); + variance=(1.0/4.0-2.0/Math.pow(Math.PI,2))*Math.pow(this.b-this.a,2); + } + + /** + * Copy-Konstruktor + * @param source Zu kopierende Ausgangsverteilung + */ + public SineDistribution(final SineDistribution source) { + this((source==null)?0:source.a,(source==null)?10:source.b); + } + + @Override + public double density(double x) { + if (x<=a || x>=b) return 0; + x=(x-a)/(b-a); + return pdfFactor*Math.sin(Math.PI*x); + } + + @Override + public double cumulativeProbability(double x) { + if (x<=a) return 0; + if (x>=b) return 1; + x=(x-a)/(b-a); + + return 0.5*(1.0-Math.cos(Math.PI*x)); + } + + @Override + public SineDistribution clone() { + return new SineDistribution(a,b); + } + + @Override + public double getNumericalMean() { + return (a+b)/2; + } + + @Override + public double getNumericalVariance() { + return variance; + } + + @Override + public double getSupportLowerBound() { + return a; + } + + @Override + public double getSupportUpperBound() { + return b; + } + + @Override + public boolean isSupportLowerBoundInclusive() { + return true; + } + + @Override + public boolean isSupportUpperBoundInclusive() { + return true; + } + + @Override + public boolean isSupportConnected() { + return true; + } + + @Override + public double inverseCumulativeProbability(final double p) throws OutOfRangeException { + if (p<0.0 || p>1.0) throw new OutOfRangeException(p,0,1); + + if (p==0.0) return getSupportLowerBound(); + if (p==1.0) return getSupportUpperBound(); + + /* p=1/2*(1-cos(pi*x)) <=> x=arccos(1-2p)/pi */ + final double z=Math.acos(1.0-2.0*p)/Math.PI; + return z*(b-a)+a; + } + + @Override + public double random(final RandomGenerator generator) { + return inverseCumulativeProbability(generator.nextDouble()); + } +} diff --git a/SimSystem/src/main/java/mathtools/distribution/UQuadraticDistribution.java b/SimSystem/src/main/java/mathtools/distribution/UQuadraticDistribution.java new file mode 100644 index 0000000..67c834e --- /dev/null +++ b/SimSystem/src/main/java/mathtools/distribution/UQuadraticDistribution.java @@ -0,0 +1,174 @@ +/** + * Copyright 2024 Alexander Herzog + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package mathtools.distribution; + +import java.io.Serializable; + +import org.apache.commons.math3.distribution.AbstractRealDistribution; +import org.apache.commons.math3.exception.OutOfRangeException; +import org.apache.commons.math3.random.RandomGenerator; + +/** + * Klasse zur Abbildung der U-quadratischen Verteilung + * @author Alexander Herzog + */ +public class UQuadraticDistribution extends AbstractRealDistribution implements Cloneable, Serializable, DistributionWithRandom { + /** + * Serialisierungs-ID der Klasse + * @see Serializable + */ + private static final long serialVersionUID=-5840683091205876418L; + + /** + * Untere Grenze des Trägers + */ + public final double a; + + /** + * Obere Grenze des Trägers + */ + public final double b; + + /** + * Vorab berechneter Faktor 1 der Dichte + */ + private final double pdfFactor1; + + /** + * Vorab berechneter Faktor 2 der Dichte + */ + private final double pdfFactor2; + + /** + * Vorab berechneter Faktor 1 der Verteilungsfunktion + */ + private final double cdfFactor1; + + /** + * Vorab berechneter Faktor 2 der Verteilungsfunktion + */ + private final double cdfFactor2; + + /** + * Vorab berechneter Faktor 3 der Verteilungsfunktion + */ + private final double cdfFactor3; + + /** + * Vorab berechneter Faktor für die Pseudozufallszahlen + */ + private final double randomFactor; + + /** + * Konstruktor + * @param a Untere Grenze des Trägers + * @param b Obere Grenze des Trägers + */ + public UQuadraticDistribution(final double a, final double b) { + super(null); + this.a=a; + this.b=Math.max(a+0.0001,b); + pdfFactor1=12.0/(this.b-this.a)/(this.b-this.a)/(this.b-this.a); + pdfFactor2=(this.a+this.b)/2.0; + cdfFactor1=4.0/(this.b-this.a)/(this.b-this.a)/(this.b-this.a); + cdfFactor2=(this.a+this.b)/2.0; + cdfFactor3=((this.a+this.b)/2.0-this.a)*((this.a+this.b)/2.0-this.a)*((this.a+this.b)/2.0-this.a); + randomFactor=(this.b-this.a)*(this.b-this.a)*(this.b-this.a)/4.0; + } + + /** + * Copy-Konstruktor + * @param source Zu kopierende Ausgangsverteilung + */ + public UQuadraticDistribution(final UQuadraticDistribution source) { + this((source==null)?0:source.a,(source==null)?10:source.b); + } + + @Override + public double density(double x) { + if (xb) return 0; + return pdfFactor1*(x-pdfFactor2)*(x-pdfFactor2); + } + + @Override + public double cumulativeProbability(double x) { + if (x<=a) return 0; + if (x>=b) return 1; + return cdfFactor1*((x-cdfFactor2)*(x-cdfFactor2)*(x-cdfFactor2)+cdfFactor3); + } + + @Override + public UQuadraticDistribution clone() { + return new UQuadraticDistribution(a,b); + } + + @Override + public double getNumericalMean() { + return (a+b)/2; + } + + @Override + public double getNumericalVariance() { + return 3.0/20.0*(b-a)*(b-a); + } + + @Override + public double getSupportLowerBound() { + return a; + } + + @Override + public double getSupportUpperBound() { + return b; + } + + @Override + public boolean isSupportLowerBoundInclusive() { + return true; + } + + @Override + public boolean isSupportUpperBoundInclusive() { + return true; + } + + @Override + public boolean isSupportConnected() { + return true; + } + + @Override + public double inverseCumulativeProbability(final double p) throws OutOfRangeException { + if (p<0.0 || p>1.0) throw new OutOfRangeException(p,0,1); + + if (p==0.0) return getSupportLowerBound(); + if (p==1.0) return getSupportUpperBound(); + + /* + p=4/(b-a)^3*[(x-(a+b)/2)^3+((a+b)/2-a)^3] + p*(b-a)^3/4-((a+b)/2-a)^3=(x-(a+b)/2)^3 + [p*(b-a)^3/4-((a+b)/2-a)^3]^(1/3)+(a+b)/2=x + */ + + final double z=p*randomFactor-cdfFactor3; + return Math.signum(z)*Math.pow(Math.abs(z),1.0/3.0)+cdfFactor2; + } + + @Override + public double random(final RandomGenerator generator) { + return inverseCumulativeProbability(generator.nextDouble()); + } +} diff --git a/SimSystem/src/main/java/mathtools/distribution/swing/JDataLoader.java b/SimSystem/src/main/java/mathtools/distribution/swing/JDataLoader.java index 65af8e0..4834d93 100644 --- a/SimSystem/src/main/java/mathtools/distribution/swing/JDataLoader.java +++ b/SimSystem/src/main/java/mathtools/distribution/swing/JDataLoader.java @@ -495,7 +495,7 @@ private static MultiTable loadDataToMultiTable(final Component owner, final Stri * @param file Tabellendatei * @return Liefert im Erfolgsfall eine {@link MultiTable}, sonst null. */ - private static MultiTable loadTable(final Component owner, final File file) { + public static MultiTable loadTable(final Component owner, final File file) { MultiTable multiTable=new MultiTable(); if (!multiTable.load(file)) { if (file!=null) JOptionPane.showMessageDialog(owner,String.format(ImportErrorFileError,file.toString()),ImportErrorTitle,JOptionPane.ERROR_MESSAGE); @@ -510,7 +510,7 @@ private static MultiTable loadTable(final Component owner, final File file) { * @param fileLoadTitle Titel des Dateiladedialogs * @return Liefert im Erfolgsfall eine {@link MultiTable}, sonst null. */ - private static MultiTable loadTable(final Component owner, final String fileLoadTitle) { + public static MultiTable loadTable(final Component owner, final String fileLoadTitle) { File file=Table.showLoadDialog(owner,fileLoadTitle); if (file==null) return null; MultiTable multiTable=loadTable(owner,file); if (multiTable==null) return null; @@ -684,7 +684,7 @@ private static double[] loadNumbersFromMultiTable(Component owner, final MultiTa * @see #loadNumbersTwoRowsFromFile(Component, File, int, int) * @see #loadNumbersTwoRowsFromString(Component, String, int, int) */ - private static double[][] loadNumbersTwoRowsFromMultiTable(Component owner, final MultiTable multiTable, final int minValues, final int maxValues) { + public static double[][] loadNumbersTwoRowsFromMultiTable(Component owner, final MultiTable multiTable, final int minValues, final int maxValues) { double[][] newData=multiTable.getNumbersTwoLines(minValues,maxValues); if (newData==null) { while (owner!=null && !(owner instanceof Window)) owner=owner.getParent(); diff --git a/SimSystem/src/main/java/mathtools/distribution/swing/JDistributionEditorPanelRecord.java b/SimSystem/src/main/java/mathtools/distribution/swing/JDistributionEditorPanelRecord.java index 8add8d3..363fb4a 100644 --- a/SimSystem/src/main/java/mathtools/distribution/swing/JDistributionEditorPanelRecord.java +++ b/SimSystem/src/main/java/mathtools/distribution/swing/JDistributionEditorPanelRecord.java @@ -28,11 +28,13 @@ import org.apache.commons.math3.distribution.UniformRealDistribution; import mathtools.NumberTools; +import mathtools.distribution.ArcsineDistribution; import mathtools.distribution.ChiDistributionImpl; import mathtools.distribution.DataDistributionImpl; import mathtools.distribution.DiscreteBinomialDistributionImpl; import mathtools.distribution.DiscreteHyperGeomDistributionImpl; import mathtools.distribution.DiscreteNegativeBinomialDistributionImpl; +import mathtools.distribution.DiscreteNegativeHyperGeomDistributionImpl; import mathtools.distribution.DiscretePoissonDistributionImpl; import mathtools.distribution.DiscreteUniformDistributionImpl; import mathtools.distribution.DiscreteZetaDistributionImpl; @@ -43,7 +45,9 @@ import mathtools.distribution.HalfNormalDistribution; import mathtools.distribution.HyperbolicSecantDistributionImpl; import mathtools.distribution.InverseGaussianDistributionImpl; +import mathtools.distribution.IrwinHallDistribution; import mathtools.distribution.JohnsonDistributionImpl; +import mathtools.distribution.KumaraswamyDistribution; import mathtools.distribution.LaplaceDistributionImpl; import mathtools.distribution.LevyDistribution; import mathtools.distribution.LogLogisticDistributionImpl; @@ -55,13 +59,17 @@ import mathtools.distribution.PertDistributionImpl; import mathtools.distribution.PowerDistributionImpl; import mathtools.distribution.RayleighDistributionImpl; +import mathtools.distribution.ReciprocalDistribution; import mathtools.distribution.SawtoothLeftDistribution; import mathtools.distribution.SawtoothRightDistribution; +import mathtools.distribution.SineDistribution; import mathtools.distribution.StudentTDistributionImpl; import mathtools.distribution.TrapezoidDistributionImpl; import mathtools.distribution.TriangularDistributionImpl; +import mathtools.distribution.UQuadraticDistribution; import mathtools.distribution.tools.AbstractDistributionWrapper; import mathtools.distribution.tools.DistributionTools; +import mathtools.distribution.tools.WrapperArcsineDistribution; import mathtools.distribution.tools.WrapperBetaDistribution; import mathtools.distribution.tools.WrapperBinomialDistribution; import mathtools.distribution.tools.WrapperCauchyDistribution; @@ -80,7 +88,9 @@ import mathtools.distribution.tools.WrapperHyperGeomDistribution; import mathtools.distribution.tools.WrapperHyperbolicSecantDistribution; import mathtools.distribution.tools.WrapperInverseGaussianDistribution; +import mathtools.distribution.tools.WrapperIrwinHallDistribution; import mathtools.distribution.tools.WrapperJohnsonDistribution; +import mathtools.distribution.tools.WrapperKumaraswamyDistribution; import mathtools.distribution.tools.WrapperLaplaceDistribution; import mathtools.distribution.tools.WrapperLevyDistribution; import mathtools.distribution.tools.WrapperLogLogisticDistribution; @@ -88,6 +98,7 @@ import mathtools.distribution.tools.WrapperLogisticDistribution; import mathtools.distribution.tools.WrapperMaxwellBoltzmannDistribution; import mathtools.distribution.tools.WrapperNegativeBinomialDistribution; +import mathtools.distribution.tools.WrapperNegativeHyperGeomDistribution; import mathtools.distribution.tools.WrapperNormalDistribution; import mathtools.distribution.tools.WrapperOnePointDistribution; import mathtools.distribution.tools.WrapperParetoDistribution; @@ -95,11 +106,14 @@ import mathtools.distribution.tools.WrapperPoissonDistribution; import mathtools.distribution.tools.WrapperPowerDistribution; import mathtools.distribution.tools.WrapperRayleighDistribution; +import mathtools.distribution.tools.WrapperReciprocalDistribution; import mathtools.distribution.tools.WrapperSawtoothLeftDistribution; import mathtools.distribution.tools.WrapperSawtoothRightDistribution; +import mathtools.distribution.tools.WrapperSineDistribution; import mathtools.distribution.tools.WrapperStudentTDistribution; import mathtools.distribution.tools.WrapperTrapezoidDistribution; import mathtools.distribution.tools.WrapperTriangularDistribution; +import mathtools.distribution.tools.WrapperUQuadraticDistribution; import mathtools.distribution.tools.WrapperUniformRealDistribution; import mathtools.distribution.tools.WrapperWeibullDistribution; import mathtools.distribution.tools.WrapperZetaDistribution; @@ -296,9 +310,16 @@ public static int compare(final JDistributionEditorPanelRecord record1, final JD allRecords.add(new BinomialDistributionPanel()); allRecords.add(new PoissonDistributionPanel()); allRecords.add(new NegativeBinomialDistributionPanel()); + allRecords.add(new NegativeHyperGeomDistributionPanel()); allRecords.add(new ZetaDistributionPanel()); allRecords.add(new DiscreteUniformDistributionPanel()); allRecords.add(new HalfNormalDistributionPanel()); + allRecords.add(new UQuadraticDistributionPanel()); + allRecords.add(new ReciprocalDistributionPanel()); + allRecords.add(new KumaraswamyDistributionPanel()); + allRecords.add(new IrwinHallDistributionPanel()); + allRecords.add(new SineDistributionPanel()); + allRecords.add(new ArcsineDistributionPanel()); } /** @@ -1153,7 +1174,7 @@ public String[] getEditValues(double meanD, String mean, double stdD, String std public String[] getValues(AbstractRealDistribution distribution) { return new String[] { NumberTools.formatNumberMax(((org.apache.commons.math3.distribution.GumbelDistribution)distribution).getNumericalMean()), - NumberTools.formatNumberMax(Math.sqrt(((org.apache.commons.math3.distribution.GumbelDistribution)distribution).getNumericalVariance())) + NumberTools.formatNumberMax(NumberTools.reduceDigits(Math.sqrt(((org.apache.commons.math3.distribution.GumbelDistribution)distribution).getNumericalVariance()),14)) }; } @@ -1386,6 +1407,222 @@ public AbstractRealDistribution getDistribution(JTextField[] fields, double maxX } } + /** U-quadratische Verteilung */ + private static class UQuadraticDistributionPanel extends JDistributionEditorPanelRecord { + /** Konstruktor der Klasse */ + public UQuadraticDistributionPanel() { + super(new WrapperUQuadraticDistribution(),new String[]{JDistributionEditorPanel.DistUniformStart,JDistributionEditorPanel.DistUniformEnd}); + } + + @Override + public String[] getEditValues(final double meanD, final String mean, final double stdD, final String std, final String lower, final String upper, final double maxXValue) { + return new String[]{lower,upper}; + } + + @Override + public String[] getValues(final AbstractRealDistribution distribution) { + return new String[] { + NumberTools.formatNumberMax(((UQuadraticDistribution)distribution).getSupportLowerBound()), + NumberTools.formatNumberMax(((UQuadraticDistribution)distribution).getSupportUpperBound()) + }; + } + + @Override + public void setValues(final JTextField[] fields, final double mean, final double sd) { + UQuadraticDistribution distribution=(UQuadraticDistribution)wrapper.getDistribution(mean,sd); + if (distribution!=null) { + if (distribution.getSupportLowerBound()<0) distribution=new UQuadraticDistribution(0,mean*2); + final String[] text=getValues(distribution); + if (text!=null && text.length==fields.length) for (int i=0;i=d2) return null; + return new UQuadraticDistribution(d1,d2); + } + } + + /** Reziproke Verteilung */ + private static class ReciprocalDistributionPanel extends JDistributionEditorPanelRecord { + /** Konstruktor der Klasse */ + public ReciprocalDistributionPanel() { + super(new WrapperReciprocalDistribution(),new String[]{JDistributionEditorPanel.DistUniformStart,JDistributionEditorPanel.DistUniformEnd}); + } + + @Override + public String[] getEditValues(final double meanD, final String mean, final double stdD, final String std, final String lower, final String upper, final double maxXValue) { + return new String[]{lower,upper}; + } + + @Override + public String[] getValues(final AbstractRealDistribution distribution) { + return new String[] { + NumberTools.formatNumberMax(((ReciprocalDistribution)distribution).getSupportLowerBound()), + NumberTools.formatNumberMax(((ReciprocalDistribution)distribution).getSupportUpperBound()) + }; + } + + @Override + public void setValues(final JTextField[] fields, final double mean, final double sd) { + ReciprocalDistribution distribution=(ReciprocalDistribution)wrapper.getDistribution(mean,sd); + if (distribution!=null) { + if (distribution.getSupportLowerBound()<0) distribution=new ReciprocalDistribution(0,mean*2); + final String[] text=getValues(distribution); + if (text!=null && text.length==fields.length) for (int i=0;i=d2) return null; + return new ReciprocalDistribution(d1,d2); + } + } + + /** Kumaraswamy-Verteilung */ + private static class KumaraswamyDistributionPanel extends JDistributionEditorPanelRecord { + /** Konstruktor der Klasse */ + public KumaraswamyDistributionPanel() { + super(new WrapperKumaraswamyDistribution(),new String[]{"a","b",JDistributionEditorPanel.DistUniformStart,JDistributionEditorPanel.DistUniformEnd}); + } + + @Override + public String[] getEditValues(final double meanD, final String mean, final double stdD, final String std, final String lower, final String upper, final double maxXValue) { + return new String[]{"1","2",lower,upper}; + } + + @Override + public String[] getValues(final AbstractRealDistribution distribution) { + return new String[] { + NumberTools.formatNumberMax(((KumaraswamyDistribution)distribution).a), + NumberTools.formatNumberMax(((KumaraswamyDistribution)distribution).b), + NumberTools.formatNumberMax(((KumaraswamyDistribution)distribution).c), + NumberTools.formatNumberMax(((KumaraswamyDistribution)distribution).d) + }; + } + + @Override + public AbstractRealDistribution getDistribution(final JTextField[] fields, final double maxXValue) { + final Double d1=NumberTools.getPositiveDouble(fields[0],true); if (d1==null) return null; + final Double d2=NumberTools.getPositiveDouble(fields[1],true); if (d2==null) return null; + final Double d3=NumberTools.getPositiveDouble(fields[2],true); if (d3==null) return null; + final Double d4=NumberTools.getPositiveDouble(fields[3],true); if (d4==null) return null; + if (d3>=d4) return null; + return new KumaraswamyDistribution(d1,d2,d3,d4); + } + } + + /** Irwin-Hall-Verteilung */ + private static class IrwinHallDistributionPanel extends JDistributionEditorPanelRecord { + /** Konstruktor der Klasse */ + public IrwinHallDistributionPanel() { + super(new WrapperIrwinHallDistribution(),new String[]{"n"}); + } + + @Override + public String[] getEditValues(final double meanD, final String mean, final double stdD, final String std, final String lower, final String upper, final double maxXValue) { + return new String[]{""+(int)Math.max(1,Math.round(meanD*2))}; + } + + @Override + public String[] getValues(final AbstractRealDistribution distribution) { + return new String[] { + ""+((IrwinHallDistribution)distribution).n + }; + } + + @Override + public AbstractRealDistribution getDistribution(final JTextField[] fields, final double maxXValue) { + final Long l=NumberTools.getPositiveLong(fields[0],true); + if (l==null) return null; + return new IrwinHallDistribution(l); + } + } + + /** Sinus-Verteilung */ + private static class SineDistributionPanel extends JDistributionEditorPanelRecord { + /** Konstruktor der Klasse */ + public SineDistributionPanel() { + super(new WrapperSineDistribution(),new String[]{JDistributionEditorPanel.DistUniformStart,JDistributionEditorPanel.DistUniformEnd}); + } + + @Override + public String[] getEditValues(final double meanD, final String mean, final double stdD, final String std, final String lower, final String upper, final double maxXValue) { + return new String[]{lower,upper}; + } + + @Override + public String[] getValues(final AbstractRealDistribution distribution) { + return new String[] { + NumberTools.formatNumberMax(((SineDistribution)distribution).getSupportLowerBound()), + NumberTools.formatNumberMax(((SineDistribution)distribution).getSupportUpperBound()) + }; + } + + @Override + public void setValues(final JTextField[] fields, final double mean, final double sd) { + SineDistribution distribution=(SineDistribution)wrapper.getDistribution(mean,sd); + if (distribution!=null) { + if (distribution.getSupportLowerBound()<0) distribution=new SineDistribution(0,mean*2); + final String[] text=getValues(distribution); + if (text!=null && text.length==fields.length) for (int i=0;i=d2) return null; + return new SineDistribution(d1,d2); + } + } + + /** Arcus Sinus-Verteilung */ + private static class ArcsineDistributionPanel extends JDistributionEditorPanelRecord { + /** Konstruktor der Klasse */ + public ArcsineDistributionPanel() { + super(new WrapperArcsineDistribution(),new String[]{JDistributionEditorPanel.DistUniformStart,JDistributionEditorPanel.DistUniformEnd}); + } + + @Override + public String[] getEditValues(final double meanD, final String mean, final double stdD, final String std, final String lower, final String upper, final double maxXValue) { + return new String[]{lower,upper}; + } + + @Override + public String[] getValues(final AbstractRealDistribution distribution) { + return new String[] { + NumberTools.formatNumberMax(((ArcsineDistribution)distribution).getSupportLowerBound()), + NumberTools.formatNumberMax(((ArcsineDistribution)distribution).getSupportUpperBound()) + }; + } + + @Override + public void setValues(final JTextField[] fields, final double mean, final double sd) { + ArcsineDistribution distribution=(ArcsineDistribution)wrapper.getDistribution(mean,sd); + if (distribution!=null) { + if (distribution.getSupportLowerBound()<0) distribution=new ArcsineDistribution(0,mean*2); + final String[] text=getValues(distribution); + if (text!=null && text.length==fields.length) for (int i=0;i=d2) return null; + return new ArcsineDistribution(d1,d2); + } + } + /** Hypergeometrische Verteilung */ private static class HyperGeomDistributionPanel extends JDistributionEditorPanelRecord { /** Konstruktor der Klasse */ @@ -1508,6 +1745,36 @@ public AbstractRealDistribution getDistribution(JTextField[] fields, double maxX } } + /** Negative Hypergeometrische Verteilung */ + private static class NegativeHyperGeomDistributionPanel extends JDistributionEditorPanelRecord { + /** Konstruktor der Klasse */ + public NegativeHyperGeomDistributionPanel() { + super(new WrapperNegativeHyperGeomDistribution(),new String[]{"N","K","n"}); + } + + @Override + public String[] getEditValues(double meanD, String mean, double stdD, String std, String lower, String upper, double maxXValue) { + return new String[]{"50","20","10"}; + } + + @Override + public String[] getValues(AbstractRealDistribution distribution) { + return new String[] { + ""+((DiscreteNegativeHyperGeomDistributionImpl)distribution).N, + ""+((DiscreteNegativeHyperGeomDistributionImpl)distribution).K, + ""+((DiscreteNegativeHyperGeomDistributionImpl)distribution).n + }; + } + + @Override + public AbstractRealDistribution getDistribution(JTextField[] fields, double maxXValue) { + final Long N=NumberTools.getPositiveLong(fields[0],true); if (N==null) return null; + final Integer K=NumberTools.getNotNegativeInteger(fields[1],true); if (K==null) return null; + final Long n=NumberTools.getPositiveLong(fields[2],true); if (n==null) return null; + return new DiscreteNegativeHyperGeomDistributionImpl(N.intValue(),K,n.intValue()); + } + } + /** Zeta-Verteilung */ private static class ZetaDistributionPanel extends JDistributionEditorPanelRecord { /** Konstruktor der Klasse */ diff --git a/SimSystem/src/main/java/mathtools/distribution/swing/JDistributionPanel.java b/SimSystem/src/main/java/mathtools/distribution/swing/JDistributionPanel.java index 49afd1f..97cb3b0 100644 --- a/SimSystem/src/main/java/mathtools/distribution/swing/JDistributionPanel.java +++ b/SimSystem/src/main/java/mathtools/distribution/swing/JDistributionPanel.java @@ -45,6 +45,7 @@ import java.io.Serializable; import java.net.URI; import java.util.List; +import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.DoubleStream; @@ -157,6 +158,8 @@ public class JDistributionPanel extends JPanel implements JGetImage { public static String RandomNumbersCount="Anzahl an zu erzeugenden Zufallszahlen"; /** Fehlermeldung wenn die angegebene Anzahl an zu erzeugenden Zufallszahlen ungültig ist */ public static String RandomNumbersError="Die Anzahl an Zufallszahlen muss eine positive Ganzzahl sein."; + /** Kontextmenü-Eintrag "In Rechenausdruck umwandeln" */ + public static String ToCalculationExpression="In Rechenausdruck umwandeln"; /** Info-Text zu der Verteilung */ private final JLabel info; @@ -188,6 +191,9 @@ public class JDistributionPanel extends JPanel implements JGetImage { /** Darstellungsmethode (Dichte, Verteilung oder beides) */ private int plotType=BOTH; + /** Optionales Callback, welches aufgerufen wird, wenn die Verteilung in einen Rechenausdruck umgewandelt werden soll */ + private final Consumer toExpression; + /** Darzustellende Verteilung */ private AbstractRealDistribution distribution=null; @@ -231,12 +237,14 @@ public class JDistributionPanel extends JPanel implements JGetImage { * @param distribution Zu ladende Verteilung (vom Typ {@link AbstractRealDistribution}) * @param maxXValue Maximal darzustellender x-Wert * @param showEditButton Soll das "Bearbeiten"-Button angezeigt werden? + * @param toExpression Optionales Callback, welches aufgerufen wird, wenn die Verteilung in einen Rechenausdruck umgewandelt werden soll * @param plotType Wählt die Darstellungsmethode (Dichte, Verteilung oder beides) */ - public JDistributionPanel(AbstractRealDistribution distribution, double maxXValue, boolean showEditButton, int plotType) { + public JDistributionPanel(AbstractRealDistribution distribution, double maxXValue, boolean showEditButton, Consumer toExpression, int plotType) { this.distribution=distribution; this.maxXValue=maxXValue; this.plotType=plotType; + this.toExpression=toExpression; setLayout(new BorderLayout(0,0)); @@ -306,6 +314,17 @@ public void mouseReleased(MouseEvent e) { }); } + /** + * Konstruktor der Klasse DistributionPanel + * @param distribution Zu ladende Verteilung (vom Typ {@link AbstractRealDistribution}) + * @param maxXValue Maximal darzustellender x-Wert + * @param showEditButton Soll das "Bearbeiten"-Button angezeigt werden? + * @param plotType Wählt die Darstellungsmethode (Dichte, Verteilung oder beides) + */ + public JDistributionPanel(AbstractRealDistribution distribution, double maxXValue, boolean showEditButton, int plotType) { + this(distribution,maxXValue,showEditButton,null,plotType); + } + /** * Konstruktor der Klasse DistributionPanel * @param distribution Zu ladende Verteilung (vom Typ AbstractContinuousDistribution) @@ -316,9 +335,20 @@ public JDistributionPanel(AbstractRealDistribution distribution, double maxXValu this(distribution,maxXValue,showEditButton,BOTH); } + /** + * Konstruktor der Klasse DistributionPanel + * @param distribution Zu ladende Verteilung (vom Typ AbstractContinuousDistribution) + * @param maxXValue Maximal darzustellender x-Wert + * @param showEditButton Soll das "Bearbeiten"-Button angezeigt werden? + * @param toExpression Optionales Callback, welches aufgerufen wird, wenn die Verteilung in einen Rechenausdruck umgewandelt werden soll + */ + public JDistributionPanel(AbstractRealDistribution distribution, double maxXValue, boolean showEditButton, Consumer toExpression) { + this(distribution,maxXValue,showEditButton,toExpression,BOTH); + } + /** * Auslesen der momentan angezeigten Verteilung - * @return Aktuell gelandene Verteilung + * @return Aktuell geladene Verteilung * @see #setDistribution(AbstractRealDistribution) * @see #setDistribution(double) */ @@ -336,6 +366,7 @@ public void setDistribution(AbstractRealDistribution distribution) { setInfoText(); repaint(); plotter.repaint(); + wiki.setVisible(DistributionTools.getDistributionWikipediaLink(distribution)!=null); } /** @@ -1125,13 +1156,22 @@ private void showContextMenu(final MouseEvent e, final boolean showEditButton) { sub.add(item=new JMenuItem(SaveButtonImage,SimSystemsSwingImages.COPY_AS_IMAGE.getIcon())); item.addActionListener(ev->saveImage()); - popup.add(item=new JMenuItem(wiki.getText(),wiki.getIcon())); - item.addActionListener(ev->actionWiki()); + if (DistributionTools.getDistributionWikipediaLink(distribution)!=null) { + popup.add(item=new JMenuItem(wiki.getText(),wiki.getIcon())); + item.addActionListener(ev->actionWiki()); + } if (showEditButton) { popup.addSeparator(); popup.add(item=new JMenuItem(edit.getText(),edit.getIcon())); item.addActionListener(ev->editButtonClicked()); + if (toExpression!=null) { + popup.add(item=new JMenuItem(ToCalculationExpression,SimSystemsSwingImages.EXPRESSION.getIcon())); + item.addActionListener(ev->{ + final String expression=DistributionTools.getCalculationExpression(getDistribution()); + if (expression!=null) toExpression.accept(expression); + }); + } } popup.show(JDistributionPanel.this,e.getX()+5,e.getY()+5); diff --git a/SimSystem/src/main/java/mathtools/distribution/swing/SimSystemsSwingImages.java b/SimSystem/src/main/java/mathtools/distribution/swing/SimSystemsSwingImages.java index 7e08a9e..2c445ec 100644 --- a/SimSystem/src/main/java/mathtools/distribution/swing/SimSystemsSwingImages.java +++ b/SimSystem/src/main/java/mathtools/distribution/swing/SimSystemsSwingImages.java @@ -81,7 +81,10 @@ public enum SimSystemsSwingImages { SETUP("cog.png"), /** Listentrenner für Verteilungsliste */ - LIST_DIVIDER("Divider.png"); + LIST_DIVIDER("Divider.png"), + + /** Symbol "f(x)" */ + EXPRESSION("fx.png"); /** * Dateiname des Icons diff --git a/SimSystem/src/main/java/mathtools/distribution/swing/res/fx.png b/SimSystem/src/main/java/mathtools/distribution/swing/res/fx.png new file mode 100644 index 0000000000000000000000000000000000000000..8ae23839ec4f07fd7d53f131d88b2161381e307b GIT binary patch literal 26467 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 OckYbS>GG4;e*ZtZ+GLFY literal 0 HcmV?d00001 diff --git a/SimSystem/src/main/java/mathtools/distribution/swing/res24/fx.png b/SimSystem/src/main/java/mathtools/distribution/swing/res24/fx.png new file mode 100644 index 0000000000000000000000000000000000000000..b96e41ed5559e63af16d65e63d87f614b6f92b58 GIT binary patch literal 26767 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�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 Lau##?#*_aAnuy1{ literal 0 HcmV?d00001 diff --git a/SimSystem/src/main/java/mathtools/distribution/swing/res48/fx.png b/SimSystem/src/main/java/mathtools/distribution/swing/res48/fx.png new file mode 100644 index 0000000000000000000000000000000000000000..25ae9343dc381708baa717ccaba85cd3a85ea9d5 GIT binary patch literal 27880 zcmbq)V{m3o@NbNbZF6I1V;dW8Y}HM;+@|0A7n9UgLeo{%!Q9ou$k_}`!N|nf!OqOo%7|3b%Gu1r!P&-z zR6(;Nk&g0fEcSn6#hlHIT&*1JN!6_E%)nS!nOWGF*;qA_+~vT)z_T2ke`$DTU#2NL z2eTlGCsO6mdi?XK9x(F`P`sKW_ze?Wt0145Vfr@jYd}0vd!fyCbpN(*(~6j8m07)f z{v+=A{?(NiDFjs%j_m(duR@gUa!KLV&O*$k!fvd2GFn?5vdt65Gg++}(*p{>-q`e;en7BsY59#95qbKzPsFMmQef$aL4!KX_M zbQEi^e?Djy<+bSjrGwD&J5@Areo}$nDSv4y>tXVRH{2$4SR{D@)}5z;8E$F>ZR!`V zJvMd1ojnv;`Q9yo3cuHT%I(Ta4D|KNn-Bc-UVQNX zK=y+Jk9c?=CuyVkzmxZWrt!TWMXd?r*^MamGCY}8c0T(76&vOb(NOzmVlR!>Buvl{NJytuS1&pGA$I;y(z%niU>;zwuwtn_!pc7%>3y5ss?}$X?@e~+jX+WcOSaD-a|Nn zQ>v4pfN#Gkbb9THu<1V@#r;O)V8r>p^%)@xSiZ$}n{UY};!$gP-a#h*cp2~mdCwB} z*W@gnI2YJiVoWY>S&7+|=JYM;@;yGIz$i7qb6O~wSPF?;>b@aN{dl~b+J$mh<;~}7 z$$l+lvw69k5_GQ@z!jEL>fNo|c6UFeER%CnjE{29LvA)ut#j#hs9i7d1&GtQtv4<= zRs1l7&Dr&t{quT>Rz+CX5l^@@8n79U^~QKnl4q3nm9<>Z&cY|XiiM{LYJ;wWs3xc+B&_po;QSt|pnu8gowpx643@649iW(t>_Ix>~C zH%x*qH@mcbaG)CN{#ilDSU?}7{8dO_XbA++n_nO+w2{f)2|D03pMOYS&#{<)e>kyd5|`$M zq-i5(G*a4`26Bs02`ZtomTB)i|2GAw@bnQ}WPk)BEbN^yxu!oU3m zr}W5>rL*aT4F2Qz=mEKZAd)fw#x~c*)?JuL@jEGy@y0jrhadr3$}42^bkqHVV`Nr@ z^4LT`nEfFNQ6(>ASPV+w?OY-36*fImGMOrCX#;r`59y-NwGBd?u`#@k)v^ZH1}5n#IP*-Vhx9%bV;tzQR-rs%FF#VkOI(n#~>IyJWVw4Jfh5t;v|6vXy-(J$(QAq6FdwME5ne~mC zW6!e@Y;3DgcKmC_?b{h1Opb|0ES4%yC@_^gcG~eDS-Yk`Dn$xYNH!896Ne)BC|%J+ zBq)WEb!5p4J4s)ifk)?nAd0ZRE4Zg*A(hu{Tf6p>r%ApuMOa=~6T=Sqw5|^ljmQ{t zgyMJqU5IB@vqUb!rT6cBkJ2Bi+-FBq;8@cwBEm0x4SYM(3Pk}(L-TgNsTQiS;o z!%|AU`T`ZuR}d1TkZN0<#1-$%w%3Ta<0{dIa&*qz@WUoC3KQPegulZIA}h;Eoo)UH z51AR6Y}hxdz<}MMeO%rvh9P!3VLzpx8Jn!$d8B*J*zbiJd2C{QLjt^z+jA# z>|7=m-ul&v)fmTq3GjlIS`-T2GWG*&cw`Z8(_Er4TNjjug6w8h2H)r(Q58}W6RTBt zhQ;cTGUteQfk`xBcRy6UoJ#M8@kqzee_}?KWJnd0(w)HtY7-_pAq!i}63way)Sh}D(ZqLQdpL|32TxQCUw-E!j}L}F z;UP`D8lt1KNzARHwa~&6;FH40VT5F@Q>n-OQDTT0OCS~)Lh;_tSROu-E6pe=Kq0y} zD~7X~`7JLJ3n4V5@E|f&1!otPyizxQZOkQv&Z>QG4-jjLUG0dx;cb+{Eze4LL)K=7xd==vj zBiZk%DJTDw)9;ehSkYNKgDR(Kn3SjAr#VBLXYQCNg5W}>;Lpk9z(U#Yj7Yv$V)q?V z#Ql^w#~kfjZeTzgOZrwZ=-Vbf@1_nmHij#pkqhn+1{ntD9k2VEcPggA=F)t~YJ4$l z-Q}1vVLPGLX@W`c_G>49dwyO~9)2=4*I|6W25T|^ceTM^ghjW)%ojL=p`5jH5*ce! zCxR`yRn?P?rvtq--pigdHy6>#gX;ElbEGX6A4DOOP{+HHRU$77kHI%;D*oQgK{aYE zAMW@bmGrL)8)GYsRlQ+af=Ve<=Cl!FnDPOVBx%~J?=|OqWG*=)N<}0y)-!cNwZ4+K zrJR|W0r}o!gG$QcSUx4c?2+zXh==n;iv_@2hWjc&I*LP7e4glRr(ZyoX@y)-pz9sV zz7FSVK0(GxvWY`5b?0M*MLkWC{w{%WX_x7LBpHegexTWaOKS2rSLIN8;hyuOR7ZoK zywpP5RoIrWWq&M>EZ&2VNB8PhcerlUik2;=s`fL{#8*C&BkdQQ!5ls1sQJrPue;^$ z>tzNb+P}&KS(iBaVoWNfIg{1&zv-;^Wq)GfUQu{}b)9ID6iI8>9Uh1S{3``v&re1Ghlpz%w^al!-jA0= zIx)4|mZsV(#-&s4o_OUO?80yUws%SPh0=xi}0;Se#OkoI@d;jG^j-rG(C`_oLQC@ibP0|0AQu_@B&lYr6ZZ$_WZo zH$k*ihM}4T;a~oubkwX8)O$GP5W)e+Ladc6IQl&|sqbz>;zvW?59!b43Npjvq>m@i zRs75l4s;}pOWit^^28~t-$Zlq2H%MAZvmMF(Szx5P6xmutjD223*l8(a-u8ui4}dS zW{aUG$%po`{#RF-t@)AwCVs!)j-4yC_$BDrk!WEY8Lku#HsAEoN8-`ra4=N6Fjec6 zuCm|X)S}u^;7WwZ(E=+=)64hVKlszZC-OTBEp&RUNMwj{M5?95-z#0>*s@jslw^L? zzwh9Lfxiglf?m{DA|vhNMr8K$yp@P*Z2xJL_WO(@31BWv^DJnx7o_dfSe`Z_IxB3} z$U@q&^8RQ*Tgset6419%A6S!7=x$DRw-Pv15xYucXzww2CXprMBL5aB0#8B)cTVfPnX;ff4)NOZ#as}jHKV7NrkSx;Wun`XOp=<1j&?C+~%nk>KMN}xpLdu6N?YVxw#IA&FW{Hu0F-S4^eAG zjdCjqZ+?>qAX~O>qNF777E60&5U>AbB9ewK(^-2(MK*@77{PIN!(2rE$L*O!8%-0c z{h}%5LniV=e1cZ)0Or|?)>3~kAO6Hy{XLz(Ra&X+{6(m4y%Ox88sF=LrLUl7s6DkG zssx&wUSTGh5}{fCol@(jn72Yc1`45iF|~rMapx3KNES7L6JJYUR@(zqu&`s54@2S! z#O%?$iC^rt)ViItJVZ|mC*m6U?$lz-hI%5A!SD2MTzT{;VyWpGMWLxx_9h#9(!eVG z{qkV@*BeDcMSRsHB~BG0mV;wnIE0MpVvw$Ox`EDR?ct4Co5m`kd+OVU+I!d5yBjL$HP&-=I48!)xT6a|sIz9RIE`ASmc{`g#rO?6}wn z?f@G04z-$pQSdgc7X(JfOXH;5TcEUJ^T&hu6`d1Q zR^oNF720;li4W3qwRD$%-}Z3Csi9@{`@fMje_>_;CVISv{G6TjUf+)cGw5pi>M`~y2T}&K6S~9%CtQR#<(Tu_p6&4LEQO)+v2C(ISt|*XFipJ zolp|^P*e{$9fM@f(Ur&Yzgz|3*W~}~><8DOUcHh!iRPMxMB*?m^Ckpen&NkSCgOEv zpKh|ZSU!_sL1UL^iSZj(s@5Lz4nIFD#Oa*fF8(nBB}?QCYbfnzsqE0^e%qO8>A1hP zpbcyW;EfFOR!K^Jh(%5HO%Y`0_)}$ozA=9MVsjmvF@O@&kPTzP^S;FMcF8EZ-sZ-l&zycRP)o(E#gp4HIxim*qQe^A>pHCA| ziKQWSQ6v7Xje*to!g)FwH?$}+J#I2Sc0SY_n>wGKLTS6JHa$ry7*Fx|Z*0!+3`)mc z^?yqK$B{}S%%K`_+NQsjb!S>_)AiD*cNv?~awbHn`+vpGo4&*@k{bRKvq;O%p{n$Y z_@8&`Rd>?kwVR%J1k6F7>YEn#JyWxVA%kXyJ65#VbR33fj15c)tZS%bXuR!{wwAE8 zNvmZHn6c6}*re2if9?}HX>?2ObPx?N<<;Opl5le(2&$eK?f3aAwCjzwa}P&wlwC#A zkZ*W9pJ`LHR2N9G$=SUjHvSFcsY-7aI9|g(RN%q)?SDjaf!UF{vdg*swL(71FgGy$ z1OKn|Y@e7^(Ot~zc$CDr+prmfwd|U6OI>;338uN_yGfLb=!+jNP-~@->%;iR8Us)J z|Ms3{oc~E$AlH+GHl^-8qBnohXZQS;ix6SYo=uD>WtXhIRciXU51Af@9b>2L;u=hL zI54~o(~Bc)kYU%d{^7Jbm#6A58!OiJ!i>W_^0pp7_PsrUDJLzGBJok(?U7xAga-dD zcv^-5mk3m^Fvyx<_x(bz6H9&jlSs1)$-=vsXhNeKQlOPI!5?Jdv&pQAvcVgwKGjUjlRd1~r@B++=VAjxlEEcO!Zu_1v*nacf;lGaC@?fmHP+zRpAS-lhH_p7cK2P_mx_(PiK9yvFZ*OQGc>Q|`3SEmZt9 zg1BlNnh&CP_DKh=-SCkK>lC6PBoOf*J>qQ_`z#v* zX6ZcsSu!^f%N&xh;Pm^PO3jfG60!AYuXFdwvB(Ji?)f)o!(*-|$SenHG5k|@FuNJx zyMOn~0=cJX!}7D-P@vHP-!jjuZ0*_Z0cjC%S9Hs@4F2|AVjSBHCyW0|Lf$5-RpWr% zp7_~b{J0W6Ro|TYb1MTrC1(7Oct#3s1G+>5x_LrM`4%nxE!-dco+2acn_CZ`X2$Ls zqbv(d9hN(k^s;UmP-{EM`40Q6>aQJcNn(?vD1;J;>of5Zm69^p?>02Qq|K6N1oqE! zSAn62h@X0sFY0zRkU-+UGP5!;#AKI!?wog&QZx^&ItiQ9-SD|BtQP|xZ`vaiYdR<~ zNagnt?0-oK=*+_;yrhOb#V*81U_%ysyVUcoy*?bdui>7r8wFagC?*k(A0|Bcdc}yM zLG-T!Cs_UT`bs__JY76X_jNuf0^Sl_neP>wVuq*v1 z<>=eOP$Ti5;F!{YE)kw>82{n3+4es&F=aL!>y=84Q9Y}IsS0<0xf5q$w2q+xrJgnQ z%1!S)qo%SW_Tx# zXYPW=+z_4+K+3dphd)W=f(Y_SEW;YxiAU_-Jl!i@QiPDBFy&`0XS;r*2k<_0#Q&XX zeg1Uh8X0m-fXsiSdmWbQ2a@KLj(6GvZQbw{p(3{9wlW}Y$Ug0x1&cv?Eq5j}Vvmi- z3Ff-Fn*hW6tjwEtpSBNF1G_o11xwuWay0iq@@rwin}B{?w!yCC%*U*ttAFEm2J@NZ zyqz}^A@HOaAm?%C@iS~W`pPgwVB=KPKin68uon7QPP4v?`Xi#NGLEE9qkyFDcrJd0 z-R(W1tNn|?J$p;>gh(W0JU#c-DSd#iE{b2VIe9??Z~_y(kp}nz^k{ASEq?F{k0HI0 zst-6Iz5Q`4x4f(^6bprHo!FT`E^J(;neZe2WHV5!b6vS2qYoYZ=(*u!DXZv){6tcPF@`TjjaLp|o5Wgq4HiW^O%TG6y`v>l#;<$%R9h#3EcGu6!< zurnA~q7yVt3lO8FV$UNs;{78r^3JGv@c#XcpzD3|@KO_j<%lNF3fTeQ8^=voJQto##0LchDZcYI432($8$q5V-2=9a%D{Sgp@EM}} z%)%{GO=T_g$ZA;R95ggFBT19CW}{?>X<*SZ#@Q@*Y`ugZ`YlNuVQVD}zHob^5V;;N zFX<>?3VG|U$v41mt){~AnTP?{LGsin`@ha?Z^@m2# z(&yag$n!HSU^zN@fa$M?G4x+oU_~D`FSt0A-;l|U1|p0fMOc?sRg6MT8z;z<1j=h- z0?by1iy}B{7A6Fq-7$N;fQMC;E&coHX=&p^LXU+=0S#meP+lAun=ODPKifseR#?e(xfV0{5MtzTHq7w)2` zIF1~|f_gEzeS`7s+n(~jDx<0}DJTa^+kW+AYV!t=JwiI}GaDZ}UzW0&Elbs41hE?_ zhx3_5>!^4UNr>90WKqj~g{)01^0|8>tdqT}H(n4iVt)ZQZrbbQnjJLqPPzW*FT|DJ zt&6@~+evB#j{{p1G zguieoU;183`Xu{*zpYeDgG-#t^9GvGegYG-xbE zMctoVdB5uk^LH~7|Nb-LURw#a;vBDY{z&ZDC$kH^;;|cp5-<(1X{bd2tr-Am8IU!A zlvBxnqt!C%-W{gqqhgO`;5SSVulK`ES&f)Zfl?|pu|Y9%n{k*wGRl945{Z98|9 zHW*;TqXxC*5jv8nx0Co>x3eZ_G+nHpZ#Q{eZU)tXxfhF*{Rj=m6%Q-B6YyenPWYA8 z>N;ZhEW8?8)zNr>(hcwa>>7495X3D4xc7E={Hp+slFOsXM7zmYx_|w;kxFEs5O4Af zY@)x?z(x`n-_5Ovy_(BwtA0o7zShy>wRMJwV%%$+XntpB?s{k0J}8zMM3HwAfwi- zAh9l(*TQO;*NQ8|t_i|qpW9vyGi60CPHyqxY(V&t!Rfcnh%kJ2_dWN}knqXS3-#`D zS;7?I%RhY_IRx5oK%kLCS{N6ewC68g$-yD62W3IIc~!4xrYCBgb--=#IKQum=>adC z9G2pHiV)ik22L;t(VjiKcIWAWn*seNp@M`W1uB8Gq@hqLHsiM(>q5-#uFnaw!e?tF z%wPZxv@`ul_5cx;$UJU$htnTR#Q5laO4W**z&PQJx2<)m7%Cqg!{N{wU#`OCS6C*Y z%sXo=^^9{&RQP-lx16XLME$-2fbnSke7X9^!_ujtDn<}iWrkU{&K-iS<(A|zE;Nww z5SosmT_~XcW#lT{-WB0KL_^IVx7Vz577Q#_xBF!v^ZjC6;b)D@`HOkKzR%83j<3X^ z-OJNm+P92+KB-Vi$mhO=`#AeqeK~OBoV*^L2UC&F?70%JIO1Ldi?TM}IRQ&f0SY=F zNOlC__7gm6d}kX zyfa!drUrXmsP|NZ8E(Ne6&y<rKAs>A#LAcioRO*Z&#_wxa3ok=#wM)r~f4n^Nrh(9lw+APtnM>RHJ;Oyy^Cp2J zgUN6FC2`%k%HE=NL^-_(%C(!*F?9cI2)8iun=VZ)?WrX5)YX#Nm7FhP0*i;!TL5mc`*t0NR9y? z3bzr#k=!Vba=?eosAu@ymydf1-QG(;G^R+sU*K}Q12b^sj(#9tgnxVa810x~e>vk( zL$KoEK)|Ns9m_(C_qg zWj5xB+Hj2lrJGw1C!ly$M#fUZMtgVpn75?sS82M7UH9H$Cd1%e7D5o9volLaKK8OM z-qkLmxP{V^ZqL+zzQrDq9^DD3TbNItdC~Q`GZ}e#_xFwT`ybC4_;>d zQ?ItER;pfqS*(J5B*^%A43*Ya6VQjOL_!)&nh#M-D+y``6}3RdS!k@seVzq*!{ONY z7W%uUVi({``8g6SxT~(K20nGJ26Bv)ZKwoh7bceB1@3nk)#~l;fd=D()=d@#L_q2A z6vZ;KKRh!Rjyzp`6mQ+$0o}-(uHw$i>lmLRvoGJ3{2c}v)s(8HvT(wte=X_-JHJ8X z{)EjxNJdvF6%f|1j-~js=*UEJ;h3BZYwD%Mm+?9axzP^|8R8eOK{E&4^mkidXd?Tf zn|s_H+|RsaX7*MQ`{A-nH~PVpXTdo)T#_aNHWEZY5t9ASZ~RH0k)3jkKm}}r;~mfO zbJx?~WMt#F$tblKABkq1B;^B85_McY;qJP|-)}|FhRYPD>*X7=iI86>g1FCXkP#wy zuTA>QGW&f`tH^+mF$ZG?Qx)PTYyMPMklnFca0l#rFdydE5sfu5m{*=3C%D&vQDuWt zoWci5ufHHqjHHJrJ!KGquwX4iP&dUP_5{RX5jLFWYST6D(&PrK`?E496{>4G8p>{B zi0pGw);=z1kZ1&(f^#C3y-!s@1qmP3Y+q-hZ~gi8=Zdw;P7St&Iq{vscBHnW1P|4F z`bl@A>-?cf?OuEdib_6f?mbg=WfCcDl;aOAkAQ*~%dsOMpNFvijcbn^mIc#U1+*qy z%bax0?X}uP!Phk25wYFZ1#Q7xq>?qzR}$qsx~}g=z{P&36H^$>@B-H9Qplq0y&5cV zXY7-BLBj1wklGgAjzEvAlRu6m<*%z{N<)uNpGWzHn*wXd3*kOppX%peuC^!Z+cM(D)$E_qR>#tHssw56QEojnbTiaw%Z0;SYiUf z$x`ouylA%4jPNlQBGr%Z5!?Fy*f`qHtT|7pazDEYgAMSH^Y|~5==xJ8p<*$me0})r z@o3DjeM4{P#!e|{IbtobqeQ29)GYmv;|j80suf3vnvd}I!h}Pq%&&?D^Bq$iYVs~l zHZihsGI@%j7coE#*Y5kyrjS*s5DR~f8JtYS(;u%17`X|y1rR$Xxc7fSk-Rr%M3SNl zzL&WhnzIgx(g)oWAPX5{RtNP>?xU@wq}cD+pl_?v@+JM6>k1F9|QFzZ-)NH}nJMs9lzn)aiIlyZO0 z!ls;Fud${`5Mn_h4G04-ANM2uqtY5aVJ9dIc_j6AcmZOF1J~#+>#j6U!2%V3*E!sI z=5aBn*YX^Zy8pOt;1d7PMNjE#;P&x`Wx48tbG^)4fbZV@c^%-&nV*TsnX2Hk2`Y+Z zMnZB~MLQWhT@uLovAvB~P~%UGsK(A6qBwg~zN)A50SPN*<5+Ek4NA?CA4zzdfc%cN zpSP80-d+d9U`t~-74nt>V##TYRHc2Kzt(&MfD!`C{N<*SUzktE8ho*SM%-wAR)Nis zR{erJo^~OXhrn@3+F6JO9L-cZK}t(c{WCg!JSFn(7d4OcpzdM$E%;iqRlwTndO|yE zez5#VQslp~uiMfBJ8HLJ}yFwfd(@LAsi1|M3BJ(u0YaEw!E&wBt! z<8HF$a?|sBinBYWVUIgo_;1;t;}_HJ>F zssw`2U}t?!l&+|Pv5Knu77*{N2@GA>#4%o@=GERA!!~HOVB*bPAa4JvRHg6GSHc2{{)arRTYY;>y*h?kHEk}FNc(TNx3N7@;Y27)EcbPbO9jDZR=6d3{ zUf9h6u?agsDXB1Lw=lxquFDgGkrSwkYW^$Kv>bf3XB!lhDU;GY;U;JEXPX|*<#JBX zvhU_e2pWtRqustG!F@2FZOy6-v3-#C*$GQjYrr5@878hS+@>|7H5nm`}Kl|c} zU(_-0gM4P(lr++{On1D$;|E2e#w7#Q;G3E8OFxvckttyRC%7SS)J&qqmnV$OPV@+= zrI!Jiag{XmHXPx#{3g;AP+p*3U~_eHVGLQ^r3a^2G0;ki7%?6b-jXDaZLka)540xY z%&|tHa;xamUv51>G`#u=PTCSeYQbY7fg~&dmnPa6FAc6R0y|(EVsj)6LpVwazf$lV zxSpDPOH4#zCA#M}inuPFYxOJ^k<8Tra-bC-ZDEyL83GWQjY&kJEyq}yX zJg`-Y%zXeK*8Qpva`}g7#Q$q1+H>`$dDaeh{v#Ij-cbC{jO&@IW{)<+dX2^pX zhFw}+X>|30k?s+s&ChG+<9(BES~U-CP^%ulsG@&w8#Rb?D3=nL9LKmk17|mfdH8$+ z;&nEj$`1?_#M(k(FznwxCuFkB$_bZE$+UfQUfG3_?y_qvz84P;3ucUnCTN!%8Ea|* zODU`=$9fGR$9N!bc`57VZV)~i{$ZS@5=8Lg4eCi3hJXNMJZLQ4#9b$!hx<)s3_a)rg7TT6Zw<1% z`F5)Q+y0OLCMYoexC1+ZKIp;Q5LFz-y*Xpn&p^!fxaj8@3hv8C$p)pM7Rfi!3lnHB z3wWR4CFep%y-5e&wI4Q?>*>8X3Ws@t%(tN$duO-$OJNd3+xnoRoH^UB8yEO|k391$ ztx-Q(6ZKZrNrh9ceO}^&L`HOhOly|iSZJ@J;*&eZVG)a&07WQ8wnB^YYf8b`cluke zP@i=qDNGSPlhy7i&>yay89Qi1`yhNy_k2K%7l#)wsPVzJ`!$Xq8(6T#iQ<(Uu)y7# z!Hh3VI2J^(?e z@aj9>A82PqFX@cP#<%cRV1lm^mbZ`thu3O~Axz9Mmi)(R8V&5piywG|LAY=vpu9nx zjn1*uM9EYq0rjk!=bmZKsOp*)a`WUTQ*8>8DMO327L;#^-Dj9$-4xfU2FTTKiLV*e zzNAxWaCgwq?pw{%PtzdI+gA(AdRBu%SQ&Y|Z6S~-w=Q#RMg3BiG}U*n@yFXBJPwzL z4+#Qyg~)q%;t#?HA`oCmoVgUbOsnec2AOs61z>q6MAdyfQ><1_F%(K+4E5><0zFzD zGNRW**vBk~SD)0~>8^QM$2USlbnz^_!8KT|qEbpBQ|v`U8TJcI8K9AtwnX86;%C02 zgvJYrC5zQ-32OOPoh=w#`@4)PJvdJ0x8s27-{5Hu^In<6A+I`F=SZ@Q(Z|kq7JANO z9~`FSXzax7?^vYqOSf?KqJRbn2L55xHnk&grnR1l`{y4u>;S2RWim*=7&*LwO;g)L zVsoY4WwR;kB%VR&O0)t~J5KF=Cmnm)F}{~0iU-~(w+O-{ACTDYJ&9N{2xdYrB`X4?dh9CH4ebpwv9oKjbi#LDf$vYagCE=Y22=hd znG-wFdUI@m(4H+&NSSA?ZH61~0Sk>5i+h(}tRv|y)!Rrk0wQ=)K~NEegFcPsVm8W) zT7OMAZYk0AjJKO$YD2cxNLtroSG*Hu5E8CZt8M*A7uOR(|cubrZ3oM5X#nb zvGA(JN*3Ww_w|ZHAIZ z!XklL5FN|l8g!$jJ77(xDmIjdfggBvQO&chbY$wl9FP3+vTLztAY0qQ{aR8R*#^8> zg=|>$kUBK%HeW9M;1HamTLH0fcxenq!Xp(?lk~*-JBYWG9l?z8WUzEiWPyF3F%Qo&FK`EKZUE(ef_t0;4S#!`JYs&Qu)4ynlAD;rCzI9o z9y@?Kzb_FYs~rEOlorq>G2mN>;=F$sNQXoEV!uv91*4d!D(ByE8c*}UWy!3I0iT2L z&)0)~ZbT$>kZ|H|j>`~KI|T$2{(|}d;45uMuJE`mf^K+>aQmm^vE_iKyc!XjN6%_`2}Sjz>PNdK*D`9{>(=X z0Oo~LGxtS-XR)LXgCHM!G@^-jvIp{Bt{d`2bi5{~L(lQ;Y<#y-H|rk<#TXQ|5s*>d zO12b$XOKL?7g#BVVy@!74iifIg!jzukPS+S{c2D7vacRr z?*7&qnQ^Y>**{U~DaKEGBJ=5wts_*~sFxylL(4TEfl;Q2m||vFpk+%Fg73gZ>e!+q zT}6=Z!m6b9x&pz*-)M87XLxR?t5;DS z?^jVkeyFpIG%=-xQkxiWX$516_|pVqwoBt^nEqX#u)u>!EuCA)qI01$iE}2yt$+mu zq{Ie^xEJ@{e0z=vm!8}Z*h_xE;DkNoT;5wNG6zYZcL>-sJ1%Tm_}=hWcqomab-XU& z@SJ(6xqbr?FGboVMCE?2%|c%w_)vQ;Qfc=K|D_E9KtetHbyQ(KE3!5^T@~GLctvFO z{g8YfQL;vk6L;WJ#R6%TeR^3s7m_}v@8nkV0%b#@E#BKf&od+4L74~Uiqyt%$J`51 zfL_z;RXP5(Y!AF~inBeET$lQ__L$Z&bVY~+Ur+UZzqxe<^9ut~Hk7jBQ4j}*mzL#T zqN_XMY{W$6TV=N(NZADMD*Xpk0dNGM)e}eRu$|>Y?6w_pQFC5++rkxd4WW@v%b300 zJ{nuNMbU|XZNHS6F{bdPCR9(5-myQDLcb%$$le7U;^gq;s+X@n5$LjVw@(vU4$%c2 z?p-xV{Z6pmDdlW4kT%~dAI2^8;>H5%Z0(-Y1@d=Q1~CD$3{s8+`*j!vX)UK%-5#y2Bjd)Q~GP|W?Ko8ZaE`szRlE>TH0fT6e|RJgTm>L z!Uh+y6$32>S`;X>C_>V3M@;Qoah-2BtS=?%$tqTBBA}Qi)mklA$@#+EPa#@~-1A{b zAD820_Bpcs*=TB?3Q@JAWF@bkMDu4GD4Dw6&tLtovYHp!$`&3saDeuF^KC<}9s-_o zuGrz%W#Q(iL_Ism2T!%E-%nP=B>%DMIAP~)E< z<9E#!&c_v$*a=(R9u{UvLxx;wB&DBk3g;|A)eQfDJ2c}?iU!9Yo(QYb4t}4z!+K1` z{3x%K?ZU5Yvqd0AlV>I7a$(_zM(7oSkGgYut8CB%QUkCfvxgNVO;8dagipJN@2w(H zY^FWJKESgjUxr(@e|+@- zbZ<z|2Y$WUf3Z(Yqa=og}_ z;PK5w*4m0SiU>&~jGDy*JhN%Vmj2hB1Coo|Mlt7YDPF5<6Ta0Gv9*5zjqMt*95je+ zi)Rm(cW@}Px3b)G1}@LaxGBN%A+zjcg<}fqHE;f0HC_1)p>p9~u<3xk&U!*8(weY* zZqM<~O+y`2P+t=*@B!Z?(xzdborA}?-}4A|CQM&HJm!6Bzyu;)k2LnY z7kDpASMs@BAmc=@YivCfON@%Z(wcwb%O%v=2;-XGIK(A2Hq$W?#5?%*b}sb0WfI)K z63k^0pDO6r;NWdrC3C{Qcyl?Sxd3!5QmbD)N4UWtlN*Z2v`|(A zG2&+i?7@tDZn>e#%|9j`e8jH{KabnzW1_G)yeb5^+K>8i4IziA`EMI|M%<#(MwMf+wTE^{3VB`=1E%Id`K)!F!g9yPu-0gobgCD&N*J z*H0U#BO)-(31Icr83d=PuTV}3g;8rE5bK3%3YrBJO(M)m_6Ly1MsBG~oS`vTK3hTE zvxcd5Cm)j1Hg}gAg?{bmYJS?VrSC?fbSdhZ#$?a>Q zF^1!G0mG)mRZINmZp`|$8~3C3p);utq9}?25QuF8+~@ehsp#{k;%EPsA|+%P(45|| zNtn$5yBylK^IkuvN6a9$7&qAnDe*(Xt*9ChFh3C$oDXwX6;Bm5(e8Gic0`I4;h0ET z2ze+E(8P`SCGJQo`fu>Mb3smjCuYh_#YkBkK03rnPTmuTPU0*Nc@zG09=SNZGOTLw zhHJTpo^wn4nnzhqC>hpNHE2})G%oM^$IvM2S%>A-G_S5Z{{+|;^ct{!^wUM(TfXtG?!xA`;v+%^B$^8Ias zM6fJOfQ%rP+{E?A>hdkKc3oD>+Cre#c@$C+j+dNRzCKbe#9+Qc8B>!913 zY`7AI6*3|JFvzQ#njWXSAfAJv2Moa`e#RO9XlgKw{%rdOHU1(}Reyx- zOHbdCYwhVS@MRDKBV_rhxAQI$uI5i<;U;Y24DUaAL()?UDp;q>J5KVpDFEX1qNw~C zWP4JtW%{j?pW$Ibg}c+ImrmY7Z^25p=jY6={ZfK2V{AEIB)V4ECpE141`@0@)3#3{ z#w(wqBK8u~Nb!;(8=95j11xcZfop=v(yXnkG~^Qba(cDF~=E z0SP3KL@c0!ARPn}eGpMvDAG$nN~j5f5PE1Kl#oCIgw*r#+J~Zg8uTir<>^T{jCb)$YQ)pdZgUxvxI@g+>V1Q7FU4_)R&lHEd#{dz z2kxMBO&J8H+3~UEG^>t15aCO)>_#9dB#!*ErSJ0T27Uz2cs_*c1%E5vtA+2*7&cCV z4UgUJw9N_)JN09B^JL=dLL|cmR@-M=k2@iCr+hEfBX81_d-)NB=L_x@P(gmpTrvQzdaI-`(8ObP!nP@r^NAnf(osET7sKS^@Ck9 z$VRDKHh=nX1-{U;2amqlJCcpkzkj`Cbf;vbwwY1qOhY#|3XKOL=e{#k0$gQO=##7! z)jr3huVRZvvzhkSL6{>Uvv~uL7`J0Vp_6w0%}{{emy(aGnRR1JF2=QL^aVp$LT@oR{i0I=x%;&ElQ&kyO!@;@wum`vUE@MeUI9Tdsjr4~~E3E9`fXWCst={mf+TJpPcW-;x2gdxZ+ zY?3C4`o`h>2In))eaV}zS-q1T;-d3T7()h!DFHhjC zl_VdTKhnP7zSYP}(<4ia`Fcq!xlbH(+^Q~uMEitY%`GSRrB*3u_=Rz2&&g1C0TG=W zc_E2|N*Ows%d5s`-^?RPpIhJWanD(}d9%O+-gY577Z1^%7Z%%~p@I0U*|vD7h~kfI z-I(xVpWTm4<_VY-$1{%7+Lpk8-6bxSWh-UO_b??j*Gs=_wV>aI!u*ZTNu7DiqxU)iD(iz7?8(>{7DfHZ4?0``~QS~jhX6L~h6)urF7g4h#veh5`-Z06X({nj|*spgj<~(Q!@3V32$C{9XK*3ud zpwxTZA%mGct6Ps9mp$t*-Ch^a+h*wQbU`hCnlUWY6~1qlH>owrDFG#SaBLWmo4+Nw zG}x!10^j2LGh(0Ht2eeH%$BbfDHOE~YeRrx@%U>6Q5Gu`1w))?gNLG@@`gM%TS$IUs0)2gFQZoG8uR=%Zg#FdNo(7%AwNUb6B(uF=kr%%_X4rm_+mZkE`KQ`zoG4tko zorW18Epoz^o0)UcijQuE$;}?Y?^@TW+(UrojC4r>{;;(KrlQQM7cH+#%;!*7A? z41~bhEx6uh4Za66{yXQuz>L=KmyWTqR|-{v!-d~_Ze@NB-Z3C2`~>rP^up;OHrASB z2O>wH(m1f41HD>9!^v9#_jEB`Dq{(2SwZs;vqDTQ+S?Hqm#Hgi_k!Ke3b#fCE(fxU z-Tl(oxBv_87yueV+SVa`e${v%pi^3O@}AU498pAa{keG3PQ}{L+z_NAUH(spU!wlJYQOM&Q_Guk2=iCWgiC+}I zZ7-gb2+$lKFA4LIoHER1XIB!hPQvH;VZ0lTzae`2;_fQO2OA+|PA4aKS>&q^&M&Q4 z@FN+#AyTan16^?|lLV|mwm9Mcdh|a>Evp}CKf0TquCgj1aDeb{6FTi-{a+XIA2M#6 zQ1<%-S!L1Ja&N=~j~{4#t8-9z=BjLm>*A6Tq0ak;F&@vqi+=LNyYBJ9!+ZK(BGb~E z?_ZD--Tm_K#}tUm-dHA)@hC*Zj2<(eJQJK-DB!upYzAx=S?~B-5!)L*q=7uEe~2|B zSacE*uht0TZ0gfWv^{sObIeSCbABLGkX9R*9hZLbi#OdiY}nwGuStXzA}ibF4!v-0 zr^~Sh*WB)6@0I#+qo+^E1<+-R0?CIMQu8AqT>hgNWLG{P4e{KFm#mE^<|`L4Hx|Dj#`<{-(Z0(zC$zx+Gx(vh?Y(qPmrt+&Yx|9-j|jiD)+r zA5Pt;#|ggW`HQZ2D;cllh*C6UYI5pCZIEMoGO@(IjIVELu};pxhS!c|Gjx8yt{HtX zlkE7uc!#?6No2IFOO9|yA>UgSwFV>b**y}4T!g*X5U_~Iu8-{DF9m$FwGXApLhWI{ z)Mj3)_ZfYIM;h1%foqM8x=w(Y5_Z`<)(3nyQ5v9WNLIJ;7Yx{n8`Qa6ehLpJH`7!( zY{)ltI=IE zY++9t}5y%S-&^Vq3lN#sCQY4q$7qvk7>s^50Ni~FGxhBsW^Q;Rxo9{4sV0(x?bRHkp}-q zg>hE>(K)e?#MUn&Cn_*;(#Xv_!g-q*iKT$4W67cD2wN}7V$OK;04f=wf*M*>F0aDr zOH2Ns^q2~gj+Xz>*9+UvSsw1hGG~<4-&on=L?C6$cI>3TYOgto^Aze*w)fOh3N211 zCwQBAXT%xOZt{y=|81N5S{vW6vR;H7_er-qpKmT6JSN8{%MT}9eC{vrIA468xtr{M zH#A%nv1>-55ED9dW`ezu!I9P~wjm@(Zdn$t+IWHq3VY*SgukKNt7~17k zn)L7DxPAk{(22r6DyN6iyB_xRhY&)$JJzdT+R5Hv&N+|+lV7gt z6j28WRWm%z(N;Z>mgacvp~=LvTn!i?Drk(vjhXAO$Pv$tmXwKjx9x!~5OMqFT zdP#Lsk+|0^q@Xm{h!jF{fD}C}>?$lq_dkTn{%t(x7RH@H4mwR{If>l_1qDI;%nrvo zj(pFc-V0to{;Gs`!KO!}w?T|Z&!(nIS@m=3$RH0;T6U8PIBVP(xiP~t`5{-q;z3qNL?lQS||O!Fq+t>^l*I<}N@{1*Sf07pij^ zcl(hWzKb^ZE22(I>x7tJYLK(Goo=k(67g(!+pp}W*%^&s&vDX@(7r_{P9ZxCy?nsz z8?B;;jfo?=0K`&|xBkX?vOlrEL1;7}RHxRZxV)c`!bjtY?g%E(L7fG$u~znr^@gnK zdn0ZPTst7g$x+0BJ-MLi1#k_{(#@eA$S#kQ$lt&OO*&dUUmgw6k2}aJLE$vYy~}i; z+PkKhRltohoZPnaS6fL|8c= z@p07=7)p-+CImJRT)yWHtwooO2|EkMO&>XCMR}SVhu-CWw9)?*{OBsIu<-ykU;&z< zCAIb|eZQaitjI#aEZA=QR+)=y-QypYwPKT`Y6m%!%{s*&%&@rSn#$~RBJ1kYRCp7vwoSoVFh7(mJdYJ6!viMWZ_W8FFJ2SZ>eR204=ihNW75OWr zNxKct(K0#qH=(F9$(C>Rc~&^Mhcfvj zeqyPXcKY6XC%9WT`r+bGan+Z#GL`JCp|$mzo=}$&K>J@x-m3ewEaie9_mLl2xe*)k zp;5&%&%&kPFby~Kf+iSX;u=pbq3Ro&-Tqt-$`V)vQ_!VHhx84YN7o@Qs*VR7jXz~c z)sP|ocw?wX%(bT4&q@d)Lr^&eKd{FQ&J=JlOIqdy5b-PDtEJQ>S%0MF$Od7R9~)Ni zb?;#@ztblcQe_GN1X#+lXZd7m3<)KU{pN|_chFwNg!Fy7;u?fIynGR+46kxAbG zVEFxT9yX%XuQDLBa);7PpgW~#<!) zyn;PYQ9}(K=@dp3b5Y&PMxX(6FrK7mQpsn)uIW{E;M@xQWmUp|@k4+XLkgOKSsD-e zRG!HU>`iLyDR(h40=ggmf=Q_~Y;p0VV-XhhuQz6&2`%Z@t&Wgxa;rciG7M4g}_Tt!}GXP(ee2pi5fgE@xeib>tR-3h#9)$?>rQ_HZ1w zBd?fwNWj~bXZOgpsu~~Y=qdZs#6tgLNx#6;^s{9_ zWwk$n>f(!WG|le~Z*27)s$;qUpIA4%`7eAjqe$nny6{AE_9NE9HT>Wwg*2rY-K9_v z!d$;UOphKWvs$~$Ae9nfTq!o@QQnGgD3*xMW7)H(AT#X}!gU_oAZ9$48fPmX+N*O} zST=i7qU z$%_V=Ewn8}k<%HxAs68V#5qMo0Zg$CW^f6VYE4#_Hd`Pqj5O!N!tW7YLIXuSHWs+#FdnsydH<60llC4-MZKjAF|lj2@DiD2uk>>|_}h_&F>r(K|Fl+`eqS zF9dXk(W#_G)RO=tsBToI%m*>qeU-gMB$j^OMEKQ5@pz%azm3*g4p0<}Kf%6_bsr^c zR9(|6q*#r8w$e8M3W4BkE+j3J`uR63Q*bo1(dR7;&W@#)4n|bmN{pf@=}2F>BgrrR zTo|D8&B+1De$lfT+pra7mofL9MzhJ--~}mdG8?GQWJHk?Iq_N69mi^X==!@JsM=LV zuHm z%TYI&6`JZvU?tBdG>pY>PVrWsSxjZwUP1-lzXGiEJdyR{{m@EP>|Pu%*>(a3HAH~L zmFp{Lz6JL`P<|TBF5w!Z+T)^a`3Do@Y ziLlUqwhi!r;9tLBWh}U z{n(8Y%BS9c`EVrB^!9cC51FA1s>tt zVb`Rv#3Zv4LLR^fP^UT4C)o1NOFp%iHj2YubuX+u5ysDZU(a4m-E6E&Wiqn4_~Etq zh$sk>8PeFQ){w#lqWFxX&iwWA2l$q+aktL!LKnwcBMw_p1A4q~ZZ5Aox+G4PFC&aA7lqU)1tUa74nOp-SjJLDl=5uKej6x-Bt^8JFj7Wn7qJ`Vy?d?6V#GM-2yKn&eiag%5 zu6o&Znc?H+4eFtPLYsoJa>@&i11S>(@P&wo;kZ7TVT2(z?>ff1ojT@C4yIJis$(B1 z3@5DJ*pGe28;460!V~CZw!dp0EV7bzZ+=Ux7IGE2oW{UYsu&j+-Yf#-yPb$!zyZ9v zo||VSC!@S_l2ht&0VmrHcAQEYZW9p&$oJ^92>4Wu+i7+DuJgEc#8c zE4jsWw&l-?L>Lq+1MU%#@oimX?Z&3R2erRiMar|~DA@;y!yw;Qrt6j26yhPUPf_7; zgJSX2c4v5UK2Vi`A6f=lt_0yRnaY}+H4o{ zerEHM>sc*m4;{a`5V8-|{MC0%wCMG{}e|9Be^H?{D^; z4epU4#$5B7nKuDg30LWl7ph7`5afM1p$39HLzvk_17*~-{o4muwz9%Tc4Q?5dPDB% zoEavCD}tUirw9}dW#Phm!$&%ao*gt1&PTHpM1qFqB6h3@jSocUWjqe?^O8(UGQy}~ z2Kf`P!s6a#dR8$U`GE4b#!5aqh5W!|s;p{n*@6QLTWFN|p`uL)?lpOzTmxwGMFJuo zCRO>Fly&SbiyXSrR+%sg?g0@=CB*Nm%&V*0cN zD|rF)dVIdpDG{A%+rN@G!LBn#|EwSpH&EttG+l)SDtG7; zrn5Q;VI-!9@^98!lpybOa{}DXA(s7~m3a73TCNz)1%3f+`9I!UByAnU?lC9>kq;aA z{~7-a?SBIJX=KPGPZ-eaFJTe-tXXWqdN7x{z#sqjbQL}o)*YMS+=iHZH^EtYDi=ns z1YID+)JrM?7m>uNE$BSzkhgUi49~lFI`TlWfD|MUX#7mw%LAk_VJPgCm z-4+gJ}CT{Xy^FF|F!D_RI zM};6+zkm;ZFaH>+v>IQbNkm+h2Z|nYk#y#kI(chEIGx|@evv=ciRpmwC$?yI|2Fx5 zVd6iL@j|^?tM$<|xY$kw{<$HXhOwFR3<@(hZr-&zd5{=neiulu2-ZZ*l%6H#(#f@P zH7dUZPn4&sCN`7CzQ{u9rZMC|=B{zqYQMnW>eBJ0Hnh@W z$6|tMjZW$^;*gjnhy>TyGrVb#MjIpYKdVxn39Qw&CPFMtCS|aT-gW#d{J6c&(;Q3Q z%-t^YrLNr7@a;`Ex%@#_GDCI{jaRh7+d)+pn(Y9PK9wiV3XUU>Kl})n2d_<8 zR%J$C%_eJ~Q*$I2$f$tz1|XjL>svbAu&?k%U?SpmRhddl!sKg9zAhqXYN8325`MWI zsrYO+dNG|4M*T25SQH$8w-e)ojBI$CA8!6`g0gD6)Uv^sHR{Z_FfA@D1Fdcmnq zHas2@Q=d~z?}Z%O>#?f?YJ$m|T(4VCnA9JjhSFXYls?DmrWJ}qJAcQ>@2?zR3?!GdS z`V#Z(V6kNgacSVY9DK*0ubBxaFT-WASn!M9wX-)8Pu)mdCz8qJwb@yZ+TVQ4aoQ~M zF;S6cmd_dSy);02sv}FBoNOFIFdBjtQV34@!vR%eG>H-bRHG(Nc&d zzDg^?3qwQ<3Lrh}xfu4 z#PaJ6*ixAqS!;D<7Niw}sLbYP_2eFGIfu>H9?46L9z`zZjki~5!gHWm+j!-`ZY>$| z#tXzL#@7RLmENUi_-{35A?Et{P@yiQW)C>qFR3z(wmYZsB+;y#=dF-f+ExD$?#--oA27kNuv0auk<3#w%Jl>LNo=hb&H+ldIr{Mz?&zUq}AGS%~Na| zh3rQ*nVa%HOE=mhnS1;Hv<$@QuHk1FlB$nB-sGx6hRB$0UAYc4%tN#$Fq&!Hu{oU% z!>$szOfQ_UPP9$C7v300^f++QOH-!YRdJSxy+jY?FK7e(clXSmf$F%Ec#j=$lJ0#kc2iD%o7aEj1Y7oTd@)oY(l&GOpZPuCvBrNV>(-X>)JSMBxar zTaS@3`?li!npgYBZASJAjd^!Wv*>&syC=Q$X%ROLZtg(+za5O3DV zS;^Uor$@Z!b3sac2$#Y;(fu}L-fQa=l7))B$iX+D`90mbg6@X3d9fzyD6UbRJyoVx ztJH8zi^v$wF>qTxx<+H1l@O;VFTZY#<0m!7vg^TsF0;*uy`OJpENzQvDzC(1n7X=V zkaK)4;w0LJy(tekBGDn|_$=Q%S*U(zxM~BUYxtmg97z{kz{~40WZI-|$59DRH_Gx* zCZG42*L&-Yvq5$V14XB!erKPzo$oPSQy{TEhMLTe(UF?qA1n0^T^_$30)4*{(1h8M zvF49Fic>9m91B}Lzqr=x&05fwA~PALgeA^5A()zGcls=2wA_GM2^KS--35iWyZvRE z|Iev^7hh0y!fWc#{LbxoLxLv%gE;q%{{xWx*P?C28T$41rS-vG)*_{cL`o0Jlpg%+ zC9ozk^6kiJ*0UDfRcr5dbb%FK{C^et95JmE7ffWPL7yx(WCA{M94EqtEOssH>tdiq zoMS_3#>b+2LuKdVmkS?A!C_I=RdaU}12ip)Qy{4CTys1ZD#lEsK#`{__-cd@`iis? z5VR7A7$JxAH(XF;)@fjU4uB>4t#Cpb{l*6LiA)3wfnvumvj(+3xbnvGQtjB2fh+&F z;m0DTgi9~HR!c=mXl%1obZ%TVxwG8?jw=bH7Y@QQI}zi8)TUZjj7pbAIW~$KMmB05mbz!U z<4X7S`;VmeimJN7Zk~K6P$&=~-Yfmw!HZus6))f}pzno~*DyKxPEc0xd4}Xg0j&bb z=X;uV38)ZmH!H+ar^-e)4l}O%=vn18q_0XeNjGIekoF}i1N`0h={t9T195(PItHx_ zsvY+fD@ERkJ#_JKlWN>Z+vp)Lj<>~RY|g;a)DE?%|pl zsC~g*yMKo2Gq_ve&7;Ua_59LVZdlgqn_h75T>I&-y6f*0(KU&RlJU!VXC+^BL}uEx zes}N$+{n)f@T0uYJ00BGojMU`99-E>O8cEBH*H=S9l{9+g?HLWld7 zcRlEK+H-CvHQ^KKxpw3&%9xJ9IiC5?9>gxS9VJI9H-Fl<_YgBFkA?1JbnW*oUhurW za}bu?@KnQ3<=0TP;LmBn{ol^S^o@o2i7JS#z5gLzcF=FnxI?Zvd?(bT$XE5KF<$WG z#~8CBzS4eZ-kqT4uBZ&eu8(gjN(*kB*M3{r{N`(bqOKP3D6%TJ+tK%<(T>r5>aD!+ zm}b8=$G2bKyyAqNX3A%nmTu6MVOG zfqQmGHRP86!@XU(P?`HJj1KW_h^FSH;uo tXI4XB`R_DJj9`Ow{xz;y>pS^Ejy2QQbyBXL_zMtjT(i7deEI&1{{u0e5=sC7 literal 0 HcmV?d00001 diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/AbstractDistributionWrapper.java b/SimSystem/src/main/java/mathtools/distribution/tools/AbstractDistributionWrapper.java index bb58c7a..52da819 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/AbstractDistributionWrapper.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/AbstractDistributionWrapper.java @@ -15,12 +15,19 @@ */ package mathtools.distribution.tools; +import java.lang.reflect.InvocationTargetException; import java.net.URL; import javax.swing.ImageIcon; import org.apache.commons.math3.distribution.AbstractRealDistribution; +import mathtools.NumberTools; +import mathtools.distribution.AbstractDiscreteRealDistribution; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDiscreteDistribution; +import parser.symbols.distributions.CalcSymbolDistribution; + /** * Von dieser Klasse abgeleitete Klassen werden nur innerhalb von {@link DistributionTools} verwendet. * Jede dieser Klassen kapselt die Zusatzinformationen für eine {@link AbstractRealDistribution} Klasse. @@ -418,4 +425,82 @@ public final boolean compare(final AbstractRealDistribution distribution1, final if (!isForDistribution(distribution2)) return false; return compareInt(distribution1,distribution2); } + + /** + * Liefert den zu der Verteilung passenden Rechenausdruck. + * @param distribution Verteilung + * @return Rechenausdruck oder null, wenn zu der Verteilung kein Rechenausdruck ermittelt werden konnte + */ + public String getCalcExpression(final AbstractRealDistribution distribution) { + if (!isForDistribution(distribution)) return null; + return getCalcExpressionInt(distribution); + } + + /** + * Liefert die Klasse des zu der Verteilung gehörende Rechenausdrucks + * @return Rechenausdruck für die Verteilung + */ + protected Class getCalcSymbolClass() { + return null; + } + + /** + * Liefert die 1-basierenden Indices, über die über {@link #getParameter(AbstractRealDistribution, int)} + * die Werte der Parameter abgefragt werden sollen. + * @param parameterCount Gesamtanzahl an Parametern + * @return Array mit den 1-basierenden Indices für {@link #getParameter(AbstractRealDistribution, int)} (die Funktion erwartet die Indices auch 1-basierend) + */ + protected int[] getDistributionParameterIndicesForCalculationExpression(final int parameterCount) { + final int[] result=new int[parameterCount]; + for (int i=0;inull, wenn zu der Verteilung kein Rechenausdruck ermittelt werden konnte + */ + protected String getCalcExpressionInt(final AbstractRealDistribution distribution) { + final Class calcSymbolClass=getCalcSymbolClass(); + if (calcSymbolClass==null) return null; + + final int parameterCount; + final String name; + + if (distribution instanceof AbstractDiscreteRealDistribution) { + CalcSymbolDiscreteDistribution calcSymbol; + @SuppressWarnings("unchecked") + final Class calcSymbolClassDiscrete=(Class)calcSymbolClass; + try { + calcSymbol=calcSymbolClassDiscrete.getConstructor().newInstance(); + } catch (InstantiationException|IllegalAccessException|IllegalArgumentException|InvocationTargetException|NoSuchMethodException|SecurityException e) { + return null; + } + parameterCount=calcSymbol.parameterCount; + name=calcSymbol.getNames()[0]; + } else { + CalcSymbolDistribution calcSymbol; + @SuppressWarnings("unchecked") + final Class calcSymbolClassDist=(Class)calcSymbolClass; + try { + calcSymbol=calcSymbolClassDist.getConstructor().newInstance(); + } catch (InstantiationException|IllegalAccessException|IllegalArgumentException|InvocationTargetException|NoSuchMethodException|SecurityException e) { + return null; + } + parameterCount=calcSymbol.parameterCount; + name=calcSymbol.getNames()[0]; + } + + final StringBuilder result=new StringBuilder(); + result.append(name); + result.append("("); + final int[] indices=getDistributionParameterIndicesForCalculationExpression(parameterCount); + for (int i=0;i0) result.append(";"); + result.append(NumberTools.formatNumberMax(getParameterInt(distribution,indices[i]))); + } + result.append(")"); + return result.toString(); + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/DistributionFitterBase.java b/SimSystem/src/main/java/mathtools/distribution/tools/DistributionFitterBase.java index 767981a..389dc7e 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/DistributionFitterBase.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/DistributionFitterBase.java @@ -298,16 +298,16 @@ public static Object[] dataDistributionFromValues(double[][] values) { for (double d: values[0]) maxValue=Math.max(d,maxValue); maxValue=Math.ceil(maxValue); int maxIndex=(int)Math.round(maxValue); - DataDistributionImpl distribution=new DataDistributionImpl(maxValue,maxIndex+1); + DataDistributionImpl distribution=new DataDistributionImpl(maxValue+1,maxIndex+1); boolean hasFloat=false; if (values.length==1) { for (double d: values[0]) { - distribution.densityData[(int)Math.max(0,Math.min(Math.round(d),maxIndex))]++; + distribution.densityData[(int)Math.max(0,Math.min(Math.floor(d),maxIndex))]++; if (Math.abs(Math.round(d)-d)>0.0001) hasFloat=true; } } else { for (int i=0;i0.0001) hasFloat=true; if (Math.abs(Math.round(values[1][i])-values[1][i])>0.0001) hasFloat=true; } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/DistributionTools.java b/SimSystem/src/main/java/mathtools/distribution/tools/DistributionTools.java index 4066362..80ade87 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/DistributionTools.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/DistributionTools.java @@ -281,6 +281,12 @@ public final class DistributionTools { /** Wikipedia-Seite Negative Binomialverteilung */ public static String DistNegativeBinomialWikipedia="https://de.wikipedia.org/wiki/Negative_Binomialverteilung"; + /** Negative Hypergeometrische Verteilung */ + public static String[] DistNegativeHyperGeom=new String[]{"Negative hypergeometrische Verteilung"}; + + /** Wikipedia-Seite Negative Hypergeometrische Verteilung */ + public static String DistNegativeHyperGeomWikipedia="https://de.wikipedia.org/wiki/Negative_hypergeometrische_Verteilung"; + /** Zeta-Verteilung */ public static String[] DistZeta=new String[]{"Zeta-Verteilung"}; @@ -299,6 +305,42 @@ public final class DistributionTools { /** Wikipedia-Seite halbe Normalverteilung */ public static String DistHalfNormalWikipedia="https://de.wikipedia.org/wiki/Normalverteilung"; + /** U-quadratische Verteilung */ + public static String[] DistUQuadratic=new String[]{"U-quadratische Verteilung"}; + + /** Wikipedia-Seite U-quadratische Verteilung */ + public static String DistUQuadraticWikipedia="https://en.wikipedia.org/wiki/U-quadratic_distribution"; + + /** Reziproke Verteilung */ + public static String[] DistReciprocal=new String[]{"Reziproke Verteilung"}; + + /** Wikipedia-Seite Reziproke Verteilung */ + public static String DistReciprocalWikipedia="https://en.wikipedia.org/wiki/Reciprocal_distribution"; + + /** Kumaraswamy-Verteilung */ + public static String[] DistKumaraswamy=new String[]{"Kumaraswamy-Verteilung"}; + + /** Wikipedia-Seite Kumaraswamy-Verteilung */ + public static String DistKumaraswamyWikipedia="https://en.wikipedia.org/wiki/Kumaraswamy_distribution"; + + /** Irwin-Hall Verteilung */ + public static String[] DistIrwinHall=new String[]{"Irwin-Hall-Verteilung"}; + + /** Wikipedia-Seite IrwinHall-Verteilung */ + public static String DistIrwinHallWikipedia="https://de.wikipedia.org/wiki/Irwin-Hall-Verteilung"; + + /** Sinus-Verteilung */ + public static String[] DistSine=new String[]{"Sinus-Verteilung"}; + + /** Wikipedia-Seite Sine-Verteilung */ + public static String DistSineWikipedia=""; /* leide keine Wikipedia-Seite vorhanden */ + + /** Arcus Sinus-Verteilung */ + public static String[] DistArcsine=new String[]{"Arcus Sinus-Verteilung"}; + + /** Wikipedia-Seite Arcus Sine-Verteilung */ + public static String DistArcsineWikipedia=""; /* leide keine Wikipedia-Seite vorhanden */ + /** Warnung "unbekannte Verteilung" */ public static String DistUnknown="unbekannte Verteilung"; @@ -394,9 +436,16 @@ private DistributionTools() { new WrapperBinomialDistribution(), new WrapperPoissonDistribution(), new WrapperNegativeBinomialDistribution(), + new WrapperNegativeHyperGeomDistribution(), new WrapperZetaDistribution(), new WrapperDiscreteUniformDistribution(), - new WrapperHalfNormalDistribution() + new WrapperHalfNormalDistribution(), + new WrapperUQuadraticDistribution(), + new WrapperReciprocalDistribution(), + new WrapperKumaraswamyDistribution(), + new WrapperIrwinHallDistribution(), + new WrapperSineDistribution(), + new WrapperArcsineDistribution() }; } @@ -778,6 +827,17 @@ public static AbstractRealDistribution cloneAndNormalizeDistribution(final Abstr return cloned; } + /** + * Liefert den zu der Verteilung passenden Rechenausdruck. + * @param distribution Verteilung + * @return Rechenausdruck oder null, wenn zu der Verteilung kein Rechenausdruck ermittelt werden konnte + */ + public static String getCalculationExpression(final AbstractRealDistribution distribution) { + final AbstractDistributionWrapper wrapper=getWrapper(distribution); + if (wrapper!=null) return wrapper.getCalcExpression(distribution); + return null; + } + /** * Sofern es sich bei dem Parameter um ein {@link DataDistributionImpl}-Objekt handelt, werden * bei einer Kopie von diesem die Raten zu einer Dichte normalisiert und die Kopie wird zurückgegeben. diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperArcsineDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperArcsineDistribution.java new file mode 100644 index 0000000..41ad3e9 --- /dev/null +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperArcsineDistribution.java @@ -0,0 +1,152 @@ +/** + * Copyright 2024 Alexander Herzog + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package mathtools.distribution.tools; + +import org.apache.commons.math3.distribution.AbstractRealDistribution; + +import mathtools.NumberTools; +import mathtools.distribution.ArcsineDistribution; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionArcsine; + +/** + * Zusätzliche Daten für ein Objekt vom Typ {@link ArcsineDistribution} + * @author Alexander Herzog + * @see ArcsineDistribution + * @see DistributionTools + */ +public class WrapperArcsineDistribution extends AbstractDistributionWrapper { + /** + * Konstruktor der Klasse + */ + public WrapperArcsineDistribution() { + super(ArcsineDistribution.class,true,false); + } + + @Override + protected String[] getNames() { + return DistributionTools.DistArcsine; + } + + @Override + protected String getThumbnailImageName() { + return "arcsine.png"; + } + + @Override + protected String getWikipediaURL() { + return DistributionTools.DistArcsineWikipedia; + } + + @Override + protected DistributionWrapperInfo getInfoInt(final AbstractRealDistribution distribution) { + return new DistributionWrapperInfo(distribution,0.0,null); /* Schiefe=0 immer */ + } + + @Override + public AbstractRealDistribution getDistribution(final double mean, final double sd) { + /* + mean=(a+b)/2 + sd=1/8*(b-a) + + a=2*mean-b + sd=1/8*(2*b-2*mean) + + 4*sd+mean=b + */ + final double b=4.0*sd+mean; + final double a=2.0*mean-b; + return new ArcsineDistribution(a,b); + } + + @Override + public AbstractRealDistribution getDefaultDistribution() { + return getDistribution(50,100); + } + + @Override + public AbstractRealDistribution getDistributionForFit(final double mean, final double sd, final double min, final double max) { + return new ArcsineDistribution(min,max); + } + + @Override + public double getMean(final AbstractRealDistribution distribution) { + return ((ArcsineDistribution)distribution).getNumericalMean(); + } + + @Override + protected AbstractRealDistribution setMeanInt(final AbstractRealDistribution distribution, final double mean) { + final ArcsineDistribution oldDistribution=(ArcsineDistribution)distribution; + + final double delta=mean-oldDistribution.getNumericalMean(); + final double a=oldDistribution.getSupportLowerBound(); + final double b=oldDistribution.getSupportUpperBound(); + return new ArcsineDistribution(a+delta,b+delta); + } + + @Override + public double getStandardDeviation(final AbstractRealDistribution distribution) { + return Math.sqrt(((ArcsineDistribution)distribution).getNumericalVariance()); + } + + @Override + protected AbstractRealDistribution setStandardDeviationInt(final AbstractRealDistribution distribution, final double sd) { + return null; + } + + @Override + protected double getParameterInt(final AbstractRealDistribution distribution, final int nr) { + if (nr==1) return ((ArcsineDistribution)distribution).getSupportLowerBound(); + if (nr==2) return ((ArcsineDistribution)distribution).getSupportUpperBound(); + return 0.0; + } + + @Override + protected AbstractRealDistribution setParameterInt(final AbstractRealDistribution distribution, final int nr, final double value) { + if (nr==1) return new ArcsineDistribution(value,((ArcsineDistribution)distribution).getSupportUpperBound()); + if (nr==2) return new ArcsineDistribution(((ArcsineDistribution)distribution).getSupportLowerBound(),value); + return null; + } + + @Override + protected String getToStringData(final AbstractRealDistribution distribution) { + return NumberTools.formatSystemNumber(((ArcsineDistribution)distribution).getSupportLowerBound())+";"+NumberTools.formatSystemNumber(((ArcsineDistribution)distribution).getSupportUpperBound()); + } + + @Override + public AbstractRealDistribution fromString(final String data, final double maxXValue) { + final double[] values=getDoubleArray(data); + if (values.length!=2) return null; + return new ArcsineDistribution(values[0],values[1]); + } + + @Override + protected AbstractRealDistribution cloneInt(final AbstractRealDistribution distribution) { + return new ArcsineDistribution(((ArcsineDistribution)distribution).getSupportLowerBound(),((ArcsineDistribution)distribution).getSupportUpperBound()); + } + + @Override + protected boolean compareInt(final AbstractRealDistribution distribution1, final AbstractRealDistribution distribution2) { + if (Math.abs(((ArcsineDistribution)distribution1).getSupportLowerBound()-((ArcsineDistribution)distribution2).getSupportLowerBound())>DistributionTools.MAX_ERROR) return false; + if (Math.abs(((ArcsineDistribution)distribution1).getSupportUpperBound()-((ArcsineDistribution)distribution2).getSupportUpperBound())>DistributionTools.MAX_ERROR) return false; + return true; + } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionArcsine.class; + } +} diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperBetaDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperBetaDistribution.java index 81178ce..cf8ba39 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperBetaDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperBetaDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.ExtBetaDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionBeta; /** * Zusätzliche Daten für ein Objekt vom Typ {@link ExtBetaDistributionImpl} @@ -149,7 +151,15 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((ExtBetaDistributionImpl)distribution1).domainLowerBound-((ExtBetaDistributionImpl)distribution2).domainLowerBound)>DistributionTools.MAX_ERROR) return false; if (Math.abs(((ExtBetaDistributionImpl)distribution1).domainUpperBound-((ExtBetaDistributionImpl)distribution2).domainUpperBound)>DistributionTools.MAX_ERROR) return false; return true; + } + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionBeta.class; } + @Override + protected int[] getDistributionParameterIndicesForCalculationExpression(final int parameterCount) { + return new int[] {3,4,1,2}; + } } \ No newline at end of file diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperBinomialDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperBinomialDistribution.java index 16c6758..17ebb8d 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperBinomialDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperBinomialDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.DiscreteBinomialDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDiscreteDistributionBinomial; /** * Zusätzliche Daten für ein Objekt vom Typ {@link DiscreteBinomialDistributionImpl} @@ -142,4 +144,14 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (((DiscreteBinomialDistributionImpl)distribution1).n!=((DiscreteBinomialDistributionImpl)distribution2).n) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDiscreteDistributionBinomial.class; + } + + @Override + protected int[] getDistributionParameterIndicesForCalculationExpression(final int parameterCount) { + return new int[] {2,1}; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperCauchyDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperCauchyDistribution.java index d8ca26b..f3cfcb3 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperCauchyDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperCauchyDistribution.java @@ -19,6 +19,8 @@ import org.apache.commons.math3.distribution.CauchyDistribution; import mathtools.NumberTools; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionCauchy; /** * Zusätzliche Daten für ein Objekt vom Typ {@link CauchyDistribution} @@ -124,4 +126,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((CauchyDistribution)distribution1).getScale()-((CauchyDistribution)distribution2).getScale())>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionCauchy.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperChiDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperChiDistribution.java index 23623dc..9862491 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperChiDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperChiDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.ChiDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionChi; /** * Zusätzliche Daten für ein Objekt vom Typ {@link ChiDistributionImpl} @@ -120,4 +122,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (((ChiDistributionImpl)distribution1).degreesOfFreedom!=((ChiDistributionImpl)distribution2).degreesOfFreedom) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionChi.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperChiSquaredDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperChiSquaredDistribution.java index 1514f4a..3735189 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperChiSquaredDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperChiSquaredDistribution.java @@ -19,6 +19,8 @@ import org.apache.commons.math3.distribution.ChiSquaredDistribution; import mathtools.NumberTools; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionChiSquare; /** * Zusätzliche Daten für ein Objekt vom Typ {@link ChiSquaredDistribution} @@ -139,4 +141,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((ChiSquaredDistribution)distribution1).getDegreesOfFreedom()-((ChiSquaredDistribution)distribution2).getDegreesOfFreedom())>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionChiSquare.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperDataDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperDataDistribution.java index d231387..b99e3eb 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperDataDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperDataDistribution.java @@ -17,7 +17,9 @@ import org.apache.commons.math3.distribution.AbstractRealDistribution; +import mathtools.NumberTools; import mathtools.distribution.DataDistributionImpl; +import parser.symbols.distributions.CalcSymbolEmpiricalDistributionRandom; /** * Zusätzliche Daten für ein Objekt vom Typ {@link DataDistributionImpl} @@ -122,4 +124,21 @@ protected boolean compareInt(final AbstractRealDistribution distribution1, final for (int i=0;iDistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected String getCalcExpressionInt(final AbstractRealDistribution distribution) { + final String name=new CalcSymbolEmpiricalDistributionRandom().getNames()[0]; + final DataDistributionImpl dataDist=(DataDistributionImpl)distribution; + + final StringBuilder result=new StringBuilder(); + result.append(name); + result.append("("); + for (var d: dataDist.densityData) { + result.append(NumberTools.formatNumberMax(d)); + result.append(";"); + } + result.append(NumberTools.formatNumberMax(dataDist.upperBound)); + result.append(")"); + return result.toString(); + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperDiscreteUniformDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperDiscreteUniformDistribution.java index 04bddaa..05764e9 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperDiscreteUniformDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperDiscreteUniformDistribution.java @@ -18,6 +18,8 @@ import org.apache.commons.math3.distribution.AbstractRealDistribution; import mathtools.distribution.DiscreteUniformDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDiscreteDistributionUniform; /** * Zusätzliche Daten für ein Objekt vom Typ {@link DiscreteUniformDistributionImpl} @@ -138,4 +140,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (((DiscreteUniformDistributionImpl)distribution1).b!=((DiscreteUniformDistributionImpl)distribution2).b) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDiscreteDistributionUniform.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperErlangDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperErlangDistribution.java index 527d7cd..53cf49a 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperErlangDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperErlangDistribution.java @@ -159,4 +159,17 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((ErlangDistributionImpl)distribution1).getScale()-((ErlangDistributionImpl)distribution2).getScale())>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected String getCalcExpressionInt(final AbstractRealDistribution distribution) { + final ErlangDistributionImpl dist=(ErlangDistributionImpl)distribution; + final StringBuilder result=new StringBuilder(); + result.append("ErlangDist"); + result.append("("); + result.append(NumberTools.formatNumberMax(dist.getShape())); + result.append(";"); + result.append(NumberTools.formatNumberMax(dist.getScale())); + result.append(")"); + return result.toString(); + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperExponentialDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperExponentialDistribution.java index ba53486..d59a460 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperExponentialDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperExponentialDistribution.java @@ -19,6 +19,8 @@ import org.apache.commons.math3.distribution.ExponentialDistribution; import mathtools.NumberTools; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionExp; /** * Zusätzliche Daten für ein Objekt vom Typ {@link ExponentialDistribution} @@ -123,4 +125,9 @@ protected AbstractRealDistribution cloneInt(AbstractRealDistribution distributio protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRealDistribution distribution2) { return Math.abs(((ExponentialDistribution)distribution1).getMean()-((ExponentialDistribution)distribution2).getMean())<=DistributionTools.MAX_ERROR; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionExp.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperFDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperFDistribution.java index cbb1249..36f48d7 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperFDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperFDistribution.java @@ -19,6 +19,8 @@ import org.apache.commons.math3.distribution.FDistribution; import mathtools.NumberTools; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionF; /** * Zusätzliche Daten für ein Objekt vom Typ {@link FDistribution} @@ -152,4 +154,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((FDistribution)distribution1).getDenominatorDegreesOfFreedom()-((FDistribution)distribution2).getDenominatorDegreesOfFreedom())>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionF.class; + } } \ No newline at end of file diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperFatigueLifeDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperFatigueLifeDistribution.java index eb88fa3..b4f0fc7 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperFatigueLifeDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperFatigueLifeDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.FatigueLifeDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionFatigueLife; /** * Zusätzliche Daten für ein Objekt vom Typ {@link FatigueLifeDistributionImpl} @@ -119,4 +121,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((FatigueLifeDistributionImpl)distribution1).gamma-((FatigueLifeDistributionImpl)distribution2).gamma)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionFatigueLife.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperFrechetDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperFrechetDistribution.java index bcd9f4c..35e858c 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperFrechetDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperFrechetDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.FrechetDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionFrechet; /** * Zusätzliche Daten für ein Objekt vom Typ {@link FrechetDistributionImpl} @@ -120,4 +122,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((FrechetDistributionImpl)distribution1).alpha-((FrechetDistributionImpl)distribution2).alpha)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionFrechet.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperGammaDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperGammaDistribution.java index c54a58d..12c43d9 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperGammaDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperGammaDistribution.java @@ -21,6 +21,7 @@ import mathtools.NumberTools; import mathtools.distribution.OnePointDistributionImpl; +import parser.symbols.distributions.CalcSymbolDistributionGammaDirect; /** * Zusätzliche Daten für ein Objekt vom Typ {@link GammaDistribution} @@ -151,4 +152,19 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((GammaDistribution)distribution1).getScale()-((GammaDistribution)distribution2).getScale())>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected String getCalcExpressionInt(final AbstractRealDistribution distribution) { + final String name=new CalcSymbolDistributionGammaDirect().getNames()[0]; + final GammaDistribution dist=(GammaDistribution)distribution; + + final StringBuilder result=new StringBuilder(); + result.append(name); + result.append("("); + result.append(NumberTools.formatNumberMax(dist.getNumericalMean())); + result.append(";"); + result.append(NumberTools.formatNumberMax(Math.sqrt(dist.getNumericalVariance()))); + result.append(")"); + return result.toString(); + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperGumbelDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperGumbelDistribution.java index d06bbb5..3960692 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperGumbelDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperGumbelDistribution.java @@ -21,6 +21,7 @@ import mathtools.NumberTools; import mathtools.distribution.ExtBetaDistributionImpl; +import parser.symbols.distributions.CalcSymbolDistributionGumbelDirect; /** * Zusätzliche Daten für ein Objekt vom Typ {@link GumbelDistribution} @@ -130,4 +131,19 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((GumbelDistribution)distribution1).getScale()-((GumbelDistribution)distribution2).getScale())>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected String getCalcExpressionInt(final AbstractRealDistribution distribution) { + final String name=new CalcSymbolDistributionGumbelDirect().getNames()[0]; + final GumbelDistribution dist=(GumbelDistribution)distribution; + + final StringBuilder result=new StringBuilder(); + result.append(name); + result.append("("); + result.append(NumberTools.formatNumberMax(dist.getNumericalMean())); + result.append(";"); + result.append(NumberTools.formatNumberMax(NumberTools.reduceDigits(Math.sqrt(dist.getNumericalVariance()),14))); + result.append(")"); + return result.toString(); + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperHalfNormalDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperHalfNormalDistribution.java index e0eb063..7c2a9b5 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperHalfNormalDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperHalfNormalDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.HalfNormalDistribution; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionHalfNormal; /** * Zusätzliche Daten für ein Objekt vom Typ {@link HalfNormalDistribution} @@ -127,4 +129,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((HalfNormalDistribution)distribution1).mean-((HalfNormalDistribution)distribution2).mean)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionHalfNormal.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperHyperGeomDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperHyperGeomDistribution.java index a46ac5c..b6def95 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperHyperGeomDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperHyperGeomDistribution.java @@ -18,6 +18,8 @@ import org.apache.commons.math3.distribution.AbstractRealDistribution; import mathtools.distribution.DiscreteHyperGeomDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDiscreteDistributionHyperGeom; /** * Zusätzliche Daten für ein Objekt vom Typ {@link DiscreteHyperGeomDistributionImpl} @@ -120,4 +122,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (((DiscreteHyperGeomDistributionImpl)distribution1).n!=((DiscreteHyperGeomDistributionImpl)distribution2).n) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDiscreteDistributionHyperGeom.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperHyperbolicSecantDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperHyperbolicSecantDistribution.java index e2416bf..4024a6e 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperHyperbolicSecantDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperHyperbolicSecantDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.HyperbolicSecantDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionHyperbolicSecant; /** * Zusätzliche Daten für ein Objekt vom Typ {@link HyperbolicSecantDistributionImpl} @@ -128,4 +130,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((HyperbolicSecantDistributionImpl)distribution1).sigma-((HyperbolicSecantDistributionImpl)distribution2).sigma)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionHyperbolicSecant.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperInverseGaussianDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperInverseGaussianDistribution.java index 7207b68..f17af5e 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperInverseGaussianDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperInverseGaussianDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.InverseGaussianDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionInverseGaussian; /** * Zusätzliche Daten für ein Objekt vom Typ {@link InverseGaussianDistributionImpl} @@ -124,4 +126,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((InverseGaussianDistributionImpl)distribution1).mu-((InverseGaussianDistributionImpl)distribution2).mu)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionInverseGaussian.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperIrwinHallDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperIrwinHallDistribution.java new file mode 100644 index 0000000..470a604 --- /dev/null +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperIrwinHallDistribution.java @@ -0,0 +1,146 @@ +/** + * Copyright 2024 Alexander Herzog + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package mathtools.distribution.tools; + +import org.apache.commons.math3.distribution.AbstractRealDistribution; + +import mathtools.distribution.IrwinHallDistribution; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionIrwinHall; + +/** + * Zusätzliche Daten für ein Objekt vom Typ {@link IrwinHallDistribution} + * @author Alexander Herzog + * @see IrwinHallDistribution + * @see DistributionTools + */ +public class WrapperIrwinHallDistribution extends AbstractDistributionWrapper { + /** + * Konstruktor der Klasse + */ + public WrapperIrwinHallDistribution() { + super(IrwinHallDistribution.class,true,true); + } + + @Override + protected String[] getNames() { + return DistributionTools.DistIrwinHall; + } + + @Override + protected String getThumbnailImageName() { + return "normal.png"; + } + + @Override + protected String getWikipediaURL() { + return DistributionTools.DistIrwinHallWikipedia; + } + + @Override + protected DistributionWrapperInfo getInfoInt(final AbstractRealDistribution distribution) { + Double mode=null; + final IrwinHallDistribution dist=(IrwinHallDistribution)distribution; + if (dist.n>1) { + mode=dist.n/2.0; + } + return new DistributionWrapperInfo(distribution,0.0,mode); + } + + @Override + public AbstractRealDistribution getDistribution(double mean, double sd) { + return new IrwinHallDistribution(2*mean); + } + + @Override + public AbstractRealDistribution getDefaultDistribution() { + return new IrwinHallDistribution(5); + } + + @Override + public AbstractRealDistribution getDistributionForFit(final double mean, final double sd, final double min, final double max) { + return new IrwinHallDistribution(2*mean); + } + + @Override + public double getMean(final AbstractRealDistribution distribution) { + return ((IrwinHallDistribution)distribution).getNumericalMean(); + } + + @Override + protected AbstractRealDistribution setMeanInt(final AbstractRealDistribution distribution, final double mean) { + return new IrwinHallDistribution(2*mean); + } + + @Override + public double getStandardDeviation(final AbstractRealDistribution distribution) { + return Math.sqrt(((IrwinHallDistribution)distribution).getNumericalVariance()); + } + + @Override + protected AbstractRealDistribution setStandardDeviationInt(final AbstractRealDistribution distribution, final double sd) { + return new IrwinHallDistribution(12*sd); + } + + @Override + public boolean canSetMeanExact() { + return false; + } + @Override + public boolean canSetStandardDeviationExact() { + return false; + } + + @Override + protected double getParameterInt(final AbstractRealDistribution distribution, final int nr) { + if (nr==1) return ((IrwinHallDistribution)distribution).n; + return 0.0; + } + + @Override + protected AbstractRealDistribution setParameterInt(final AbstractRealDistribution distribution, final int nr, final double value) { + if (nr==1) return new IrwinHallDistribution(value); + return null; + } + + @Override + protected String getToStringData(final AbstractRealDistribution distribution) { + return ""+((IrwinHallDistribution)distribution).n; + } + + @Override + public AbstractRealDistribution fromString(final String data, final double maxXValue) { + final double[] values=getDoubleArray(data); + if (values.length!=1) return null; + return new IrwinHallDistribution(values[0]); + } + + @Override + protected AbstractRealDistribution cloneInt(final AbstractRealDistribution distribution) { + return new IrwinHallDistribution(((IrwinHallDistribution)distribution).n); + } + + @Override + protected boolean compareInt(final AbstractRealDistribution distribution1, final AbstractRealDistribution distribution2) { + if (Math.abs(((IrwinHallDistribution)distribution1).n-((IrwinHallDistribution)distribution2).n)>0) return false; + return true; + } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionIrwinHall.class; + } +} diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperJohnsonDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperJohnsonDistribution.java index c9e5e00..7742f53 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperJohnsonDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperJohnsonDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.JohnsonDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionJohnsonSU; /** * Zusätzliche Daten für ein Objekt vom Typ {@link JohnsonDistributionImpl} @@ -123,4 +125,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((JohnsonDistributionImpl)distribution1).lambda-((JohnsonDistributionImpl)distribution2).lambda)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionJohnsonSU.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperKumaraswamyDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperKumaraswamyDistribution.java new file mode 100644 index 0000000..9946129 --- /dev/null +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperKumaraswamyDistribution.java @@ -0,0 +1,148 @@ +/** + * Copyright 2024 Alexander Herzog + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package mathtools.distribution.tools; + +import org.apache.commons.math3.distribution.AbstractRealDistribution; + +import mathtools.NumberTools; +import mathtools.distribution.KumaraswamyDistribution; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionKumaraswamy; + +/** + * Zusätzliche Daten für ein Objekt vom Typ {@link KumaraswamyDistribution} + * @author Alexander Herzog + * @see KumaraswamyDistribution + * @see DistributionTools + */ +public class WrapperKumaraswamyDistribution extends AbstractDistributionWrapper { + /** + * Konstruktor der Klasse + */ + public WrapperKumaraswamyDistribution() { + super(KumaraswamyDistribution.class,false,false); + } + + @Override + protected String[] getNames() { + return DistributionTools.DistKumaraswamy; + } + + @Override + protected String getThumbnailImageName() { + return "beta.png"; + } + + @Override + protected String getWikipediaURL() { + return DistributionTools.DistReciprocalWikipedia; + } + + @Override + protected DistributionWrapperInfo getInfoInt(final AbstractRealDistribution distribution) { + Double mode=null; + final KumaraswamyDistribution dist=(KumaraswamyDistribution)distribution; + if (dist.a>=1 && dist.b>=1 && (dist.a>1 || dist.b>1)) { + mode=Math.pow((dist.a-1)/(dist.a*dist.b-1),1/dist.a)*(dist.d-dist.c)+dist.c; + } + return new DistributionWrapperInfo(distribution,null,mode); + } + + @Override + public AbstractRealDistribution getDistribution(double mean, double sd) { + return null; + } + + @Override + public AbstractRealDistribution getDefaultDistribution() { + return new KumaraswamyDistribution(1,2,50,100); + } + + @Override + public AbstractRealDistribution getDistributionForFit(final double mean, final double sd, final double min, final double max) { + return null; + } + + @Override + public double getMean(final AbstractRealDistribution distribution) { + return ((KumaraswamyDistribution)distribution).getNumericalMean(); + } + + @Override + protected AbstractRealDistribution setMeanInt(final AbstractRealDistribution distribution, final double mean) { + return null; + } + + @Override + public double getStandardDeviation(final AbstractRealDistribution distribution) { + return Math.sqrt(((KumaraswamyDistribution)distribution).getNumericalVariance()); + } + + @Override + protected AbstractRealDistribution setStandardDeviationInt(final AbstractRealDistribution distribution, final double sd) { + return null; + } + + @Override + protected double getParameterInt(final AbstractRealDistribution distribution, final int nr) { + if (nr==1) return ((KumaraswamyDistribution)distribution).a; + if (nr==2) return ((KumaraswamyDistribution)distribution).b; + if (nr==3) return ((KumaraswamyDistribution)distribution).c; + if (nr==4) return ((KumaraswamyDistribution)distribution).d; + return 0.0; + } + + @Override + protected AbstractRealDistribution setParameterInt(final AbstractRealDistribution distribution, final int nr, final double value) { + final KumaraswamyDistribution old=(KumaraswamyDistribution)distribution; + if (nr==1) return new KumaraswamyDistribution(value,old.b,old.c,old.d); + if (nr==2) return new KumaraswamyDistribution(old.a,value,old.c,old.d); + if (nr==3) return new KumaraswamyDistribution(old.a,old.b,value,old.d); + if (nr==4) return new KumaraswamyDistribution(old.a,old.b,old.c,value); + return null; + } + + @Override + protected String getToStringData(final AbstractRealDistribution distribution) { + return NumberTools.formatSystemNumber(((KumaraswamyDistribution)distribution).a)+";"+NumberTools.formatSystemNumber(((KumaraswamyDistribution)distribution).b)+";"+NumberTools.formatSystemNumber(((KumaraswamyDistribution)distribution).c)+";"+NumberTools.formatSystemNumber(((KumaraswamyDistribution)distribution).d); + } + + @Override + public AbstractRealDistribution fromString(final String data, final double maxXValue) { + final double[] values=getDoubleArray(data); + if (values.length!=4) return null; + return new KumaraswamyDistribution(values[0],values[1],values[2],values[3]); + } + + @Override + protected AbstractRealDistribution cloneInt(final AbstractRealDistribution distribution) { + return new KumaraswamyDistribution(((KumaraswamyDistribution)distribution).a,((KumaraswamyDistribution)distribution).b,((KumaraswamyDistribution)distribution).c,((KumaraswamyDistribution)distribution).d); + } + + @Override + protected boolean compareInt(final AbstractRealDistribution distribution1, final AbstractRealDistribution distribution2) { + if (Math.abs(((KumaraswamyDistribution)distribution1).a-((KumaraswamyDistribution)distribution2).a)>DistributionTools.MAX_ERROR) return false; + if (Math.abs(((KumaraswamyDistribution)distribution1).b-((KumaraswamyDistribution)distribution2).b)>DistributionTools.MAX_ERROR) return false; + if (Math.abs(((KumaraswamyDistribution)distribution1).c-((KumaraswamyDistribution)distribution2).c)>DistributionTools.MAX_ERROR) return false; + if (Math.abs(((KumaraswamyDistribution)distribution1).d-((KumaraswamyDistribution)distribution2).d)>DistributionTools.MAX_ERROR) return false; + return true; + } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionKumaraswamy.class; + } +} diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLaplaceDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLaplaceDistribution.java index 4547bcb..9e63495 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLaplaceDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLaplaceDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.LaplaceDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionLaplace; /** * Zusätzliche Daten für ein Objekt vom Typ {@link LaplaceDistributionImpl} @@ -121,4 +123,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((LaplaceDistributionImpl)distribution1).b-((LaplaceDistributionImpl)distribution2).b)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionLaplace.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLevyDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLevyDistribution.java index 7a4dfbc..3590cc4 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLevyDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLevyDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.LevyDistribution; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionLevy; /** * Zusätzliche Daten für ein Objekt vom Typ {@link LevyDistribution} @@ -51,7 +53,10 @@ protected String getWikipediaURL() { @Override protected DistributionWrapperInfo getInfoInt(AbstractRealDistribution distribution) { - return new DistributionWrapperInfo(null,null,null,null,null,null); + final double mu=((LevyDistribution)distribution).mu; + final double c=((LevyDistribution)distribution).c; + final String info="mu="+NumberTools.formatNumber(mu)+"; c="+NumberTools.formatNumber(c); + return new DistributionWrapperInfo(null,null,null,null,info,null); } @Override @@ -110,6 +115,10 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((LevyDistribution)distribution1).mu-((LevyDistribution)distribution2).mu)>DistributionTools.MAX_ERROR) return false; if (Math.abs(((LevyDistribution)distribution1).c-((LevyDistribution)distribution2).c)>DistributionTools.MAX_ERROR) return false; return true; + } + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionLevy.class; } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLogLogisticDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLogLogisticDistribution.java index a3b0b9d..8faee8b 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLogLogisticDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLogLogisticDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.LogLogisticDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionLogLogistic; /** * Zusätzliche Daten für ein Objekt vom Typ {@link LogLogisticDistributionImpl} @@ -78,6 +80,27 @@ protected AbstractRealDistribution setStandardDeviationInt(AbstractRealDistribut return null; } + @Override + public AbstractRealDistribution getDistributionForFit(final double mean, final double sd, final double min, final double max) { + if (mean<=0 || sd<=0 || min<0) return null; + + /* + factor=mean/(std**2+mean**2) + beta=pi/acos(alpha*factor) + */ + final double factor=mean/(sd*sd+mean*mean); + double alpha; + if (factor<1) { + alpha=Math.floor(1/factor); + if (alpha>1) alpha--; + } else { + alpha=1/factor; + } + final double beta=Math.PI/Math.acos(Math.min(1,alpha*factor)); + + return new LogLogisticDistributionImpl(alpha,beta); + } + @Override protected double getParameterInt(AbstractRealDistribution distribution, int nr) { if (nr==1) return ((LogLogisticDistributionImpl)distribution).alpha; @@ -115,4 +138,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((LogLogisticDistributionImpl)distribution1).beta-((LogLogisticDistributionImpl)distribution2).beta)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionLogLogistic.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLogNormalDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLogNormalDistribution.java index 03125e0..122128b 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLogNormalDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLogNormalDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.LogNormalDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionLogNormal; /** * Zusätzliche Daten für ein Objekt vom Typ {@link LogNormalDistributionImpl} @@ -128,4 +130,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((LogNormalDistributionImpl)distribution1).sd-((LogNormalDistributionImpl)distribution2).sd)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionLogNormal.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLogisticDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLogisticDistribution.java index bae5306..d724164 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLogisticDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperLogisticDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.LogisticDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionLogistic; /** * Zusätzliche Daten für ein Objekt vom Typ {@link LogisticDistributionImpl} @@ -123,4 +125,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((LogisticDistributionImpl)distribution1).s-((LogisticDistributionImpl)distribution2).s)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionLogistic.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperMaxwellBoltzmannDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperMaxwellBoltzmannDistribution.java index 1e7bc31..ed4035c 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperMaxwellBoltzmannDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperMaxwellBoltzmannDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.MaxwellBoltzmannDistribution; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionMaxwellBoltzmann; /** * Zusätzliche Daten für ein Objekt vom Typ {@link MaxwellBoltzmannDistribution} @@ -122,4 +124,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((MaxwellBoltzmannDistribution)distribution1).a-((MaxwellBoltzmannDistribution)distribution2).a)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionMaxwellBoltzmann.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperNegativeBinomialDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperNegativeBinomialDistribution.java index 6cce167..02922bc 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperNegativeBinomialDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperNegativeBinomialDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.DiscreteNegativeBinomialDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDiscreteDistributionNegativeBinomial; /** * Zusätzliche Daten für ein Objekt vom Typ {@link DiscreteNegativeBinomialDistributionImpl} @@ -141,4 +143,14 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (((DiscreteNegativeBinomialDistributionImpl)distribution1).r!=((DiscreteNegativeBinomialDistributionImpl)distribution2).r) return false; return true; } + + @Override + protected int[] getDistributionParameterIndicesForCalculationExpression(final int parameterCount) { + return new int[] {2,1}; + } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDiscreteDistributionNegativeBinomial.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperNegativeHyperGeomDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperNegativeHyperGeomDistribution.java new file mode 100644 index 0000000..c4dda78 --- /dev/null +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperNegativeHyperGeomDistribution.java @@ -0,0 +1,129 @@ +/** + * Copyright 2024 Alexander Herzog + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package mathtools.distribution.tools; + +import org.apache.commons.math3.distribution.AbstractRealDistribution; + +import mathtools.distribution.DiscreteNegativeHyperGeomDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDiscreteDistributionNegativeHyperGeom; + +/** + * Zusätzliche Daten für ein Objekt vom Typ {@link DiscreteNegativeHyperGeomDistributionImpl} + * @author Alexander Herzog + * @see DiscreteNegativeHyperGeomDistributionImpl + * @see DistributionTools + */ +public class WrapperNegativeHyperGeomDistribution extends AbstractDistributionWrapper { + /** + * Konstruktor der Klasse + */ + public WrapperNegativeHyperGeomDistribution() { + super(DiscreteNegativeHyperGeomDistributionImpl.class); + } + + @Override + protected String[] getNames() { + return DistributionTools.DistNegativeHyperGeom; + } + + @Override + protected String getThumbnailImageName() { + return "discrete.png"; + } + + @Override + protected String getWikipediaURL() { + return DistributionTools.DistNegativeHyperGeomWikipedia; + } + + @Override + protected DistributionWrapperInfo getInfoInt(AbstractRealDistribution distribution) { + final DiscreteNegativeHyperGeomDistributionImpl dist=(DiscreteNegativeHyperGeomDistributionImpl)distribution; + final double mode=dist.getMode(); + final String info1="N="+dist.N+"; K="+dist.K+"; n="+dist.n; + return new DistributionWrapperInfo(distribution,null,mode,info1,null); + } + + @Override + public AbstractRealDistribution getDistribution(double mean, double sd) { + return null; + } + + @Override + public AbstractRealDistribution getDefaultDistribution() { + return new DiscreteNegativeHyperGeomDistributionImpl(50,20,10); + } + + @Override + protected AbstractRealDistribution setMeanInt(AbstractRealDistribution distribution, double mean) { + return null; + } + + @Override + protected AbstractRealDistribution setStandardDeviationInt(AbstractRealDistribution distribution, double sd) { + return null; + } + + @Override + protected double getParameterInt(AbstractRealDistribution distribution, int nr) { + final DiscreteNegativeHyperGeomDistributionImpl dist=(DiscreteNegativeHyperGeomDistributionImpl)distribution; + if (nr==1) return dist.N; + if (nr==2) return dist.K; + if (nr==3) return dist.n; + return 0.0; + } + + @Override + protected AbstractRealDistribution setParameterInt(AbstractRealDistribution distribution, int nr, double value) { + final DiscreteNegativeHyperGeomDistributionImpl dist=(DiscreteNegativeHyperGeomDistributionImpl)distribution; + if (nr==1) return new DiscreteNegativeHyperGeomDistributionImpl((int)Math.round(value),dist.K,dist.n); + if (nr==2) return new DiscreteNegativeHyperGeomDistributionImpl(dist.N,(int)Math.round(value),dist.n); + if (nr==3) return new DiscreteNegativeHyperGeomDistributionImpl(dist.N,dist.K,(int)Math.round(value)); + return null; + } + + @Override + protected String getToStringData(AbstractRealDistribution distribution) { + final DiscreteNegativeHyperGeomDistributionImpl dist=(DiscreteNegativeHyperGeomDistributionImpl)distribution; + return ""+dist.N+";"+dist.K+";"+dist.n; + } + + @Override + public AbstractRealDistribution fromString(String data, double maxXValue) { + final double[] values=getDoubleArray(data); + if (values.length!=3) return null; + return new DiscreteNegativeHyperGeomDistributionImpl((int)Math.round(values[0]),(int)Math.round(values[1]),(int)Math.round(values[2])); + } + + @Override + protected AbstractRealDistribution cloneInt(AbstractRealDistribution distribution) { + return new DiscreteNegativeHyperGeomDistributionImpl((DiscreteNegativeHyperGeomDistributionImpl)distribution); + } + + @Override + protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRealDistribution distribution2) { + if (((DiscreteNegativeHyperGeomDistributionImpl)distribution1).N!=((DiscreteNegativeHyperGeomDistributionImpl)distribution2).N) return false; + if (((DiscreteNegativeHyperGeomDistributionImpl)distribution1).K!=((DiscreteNegativeHyperGeomDistributionImpl)distribution2).K) return false; + if (((DiscreteNegativeHyperGeomDistributionImpl)distribution1).n!=((DiscreteNegativeHyperGeomDistributionImpl)distribution2).n) return false; + return true; + } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDiscreteDistributionNegativeHyperGeom.class; + } +} diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperNormalDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperNormalDistribution.java index 67fbacf..d6efc57 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperNormalDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperNormalDistribution.java @@ -19,6 +19,8 @@ import org.apache.commons.math3.distribution.NormalDistribution; import mathtools.NumberTools; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionNormal; /** * Zusätzliche Daten für ein Objekt vom Typ {@link NormalDistribution} @@ -128,4 +130,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((NormalDistribution)distribution1).getStandardDeviation()-((NormalDistribution)distribution2).getStandardDeviation())>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionNormal.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperOnePointDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperOnePointDistribution.java index f75c281..2eb2dee 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperOnePointDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperOnePointDistribution.java @@ -124,4 +124,9 @@ protected AbstractRealDistribution cloneInt(final AbstractRealDistribution distr protected boolean compareInt(final AbstractRealDistribution distribution1, final AbstractRealDistribution distribution2) { return Math.abs(((OnePointDistributionImpl)distribution1).point-((OnePointDistributionImpl)distribution2).point)<=DistributionTools.MAX_ERROR; } + + @Override + protected String getCalcExpressionInt(final AbstractRealDistribution distribution) { + return NumberTools.formatNumberMax(((OnePointDistributionImpl)distribution).point); + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperParetoDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperParetoDistribution.java index ce792b5..e1413b0 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperParetoDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperParetoDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.ParetoDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionPareto; /** * Zusätzliche Daten für ein Objekt vom Typ {@link ParetoDistributionImpl} @@ -131,4 +133,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((ParetoDistributionImpl)distribution1).alpha-((ParetoDistributionImpl)distribution2).alpha)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionPareto.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperPertDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperPertDistribution.java index 288b7eb..53f987e 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperPertDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperPertDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.PertDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionPert; /** * Zusätzliche Daten für ein Objekt vom Typ {@link PertDistributionImpl} @@ -127,4 +129,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((PertDistributionImpl)distribution1).mostLikely-((PertDistributionImpl)distribution2).mostLikely)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionPert.class; + } } \ No newline at end of file diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperPoissonDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperPoissonDistribution.java index 9989d27..ea97686 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperPoissonDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperPoissonDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.DiscretePoissonDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDiscreteDistributionPoisson; /** * Zusätzliche Daten für ein Objekt vom Typ {@link DiscretePoissonDistributionImpl} @@ -112,4 +114,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((DiscretePoissonDistributionImpl)distribution1).lambda-((DiscretePoissonDistributionImpl)distribution2).lambda)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDiscreteDistributionPoisson.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperPowerDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperPowerDistribution.java index fc3ff91..05acde4 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperPowerDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperPowerDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.PowerDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionPower; /** * Zusätzliche Daten für ein Objekt vom Typ {@link PowerDistributionImpl} @@ -137,4 +139,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((PowerDistributionImpl)distribution1).c-((PowerDistributionImpl)distribution2).c)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionPower.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperRayleighDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperRayleighDistribution.java index ad2fae9..7571af1 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperRayleighDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperRayleighDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.RayleighDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionRayleigh; /** * Zusätzliche Daten für ein Objekt vom Typ {@link RayleighDistributionImpl} @@ -116,4 +118,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((RayleighDistributionImpl)distribution1).sigma-((RayleighDistributionImpl)distribution2).sigma)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionRayleigh.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperReciprocalDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperReciprocalDistribution.java new file mode 100644 index 0000000..1202894 --- /dev/null +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperReciprocalDistribution.java @@ -0,0 +1,137 @@ +/** + * Copyright 2024 Alexander Herzog + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package mathtools.distribution.tools; + +import org.apache.commons.math3.distribution.AbstractRealDistribution; + +import mathtools.NumberTools; +import mathtools.distribution.ReciprocalDistribution; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionReciprocal; + +/** + * Zusätzliche Daten für ein Objekt vom Typ {@link ReciprocalDistribution} + * @author Alexander Herzog + * @see ReciprocalDistribution + * @see DistributionTools + */ +public class WrapperReciprocalDistribution extends AbstractDistributionWrapper { + /** + * Konstruktor der Klasse + */ + public WrapperReciprocalDistribution() { + super(ReciprocalDistribution.class,false,false); + } + + @Override + protected String[] getNames() { + return DistributionTools.DistReciprocal; + } + + @Override + protected String getThumbnailImageName() { + return "reciprocal.png"; + } + + @Override + protected String getWikipediaURL() { + return DistributionTools.DistReciprocalWikipedia; + } + + @Override + protected DistributionWrapperInfo getInfoInt(final AbstractRealDistribution distribution) { + return new DistributionWrapperInfo(distribution,null,((ReciprocalDistribution)distribution).getSupportLowerBound()); + } + + @Override + public AbstractRealDistribution getDistribution(double mean, double sd) { + return null; + } + + @Override + public AbstractRealDistribution getDefaultDistribution() { + return new ReciprocalDistribution(50,100); + } + + @Override + public AbstractRealDistribution getDistributionForFit(final double mean, final double sd, final double min, final double max) { + if (mean<=0 || sd<=0 || min<=0 || max<=min) return null; + return new ReciprocalDistribution(min,max); + } + + @Override + public double getMean(final AbstractRealDistribution distribution) { + return ((ReciprocalDistribution)distribution).getNumericalMean(); + } + + @Override + protected AbstractRealDistribution setMeanInt(final AbstractRealDistribution distribution, final double mean) { + return null; + } + + @Override + public double getStandardDeviation(final AbstractRealDistribution distribution) { + return Math.sqrt(((ReciprocalDistribution)distribution).getNumericalVariance()); + } + + @Override + protected AbstractRealDistribution setStandardDeviationInt(final AbstractRealDistribution distribution, final double sd) { + return null; + } + + @Override + protected double getParameterInt(final AbstractRealDistribution distribution, final int nr) { + if (nr==1) return ((ReciprocalDistribution)distribution).getSupportLowerBound(); + if (nr==2) return ((ReciprocalDistribution)distribution).getSupportUpperBound(); + return 0.0; + } + + @Override + protected AbstractRealDistribution setParameterInt(final AbstractRealDistribution distribution, final int nr, final double value) { + if (nr==1) return new ReciprocalDistribution(value,((ReciprocalDistribution)distribution).getSupportUpperBound()); + if (nr==2) return new ReciprocalDistribution(((ReciprocalDistribution)distribution).getSupportLowerBound(),value); + return null; + } + + @Override + protected String getToStringData(final AbstractRealDistribution distribution) { + return NumberTools.formatSystemNumber(((ReciprocalDistribution)distribution).getSupportLowerBound())+";"+NumberTools.formatSystemNumber(((ReciprocalDistribution)distribution).getSupportUpperBound()); + } + + @Override + public AbstractRealDistribution fromString(final String data, final double maxXValue) { + final double[] values=getDoubleArray(data); + if (values.length!=2) return null; + return new ReciprocalDistribution(values[0],values[1]); + } + + @Override + protected AbstractRealDistribution cloneInt(final AbstractRealDistribution distribution) { + return new ReciprocalDistribution(((ReciprocalDistribution)distribution).getSupportLowerBound(),((ReciprocalDistribution)distribution).getSupportUpperBound()); + } + + @Override + protected boolean compareInt(final AbstractRealDistribution distribution1, final AbstractRealDistribution distribution2) { + if (Math.abs(((ReciprocalDistribution)distribution1).getSupportLowerBound()-((ReciprocalDistribution)distribution2).getSupportLowerBound())>DistributionTools.MAX_ERROR) return false; + if (Math.abs(((ReciprocalDistribution)distribution1).getSupportUpperBound()-((ReciprocalDistribution)distribution2).getSupportUpperBound())>DistributionTools.MAX_ERROR) return false; + return true; + } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionReciprocal.class; + } +} diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperSawtoothLeftDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperSawtoothLeftDistribution.java index 8441111..cafafc3 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperSawtoothLeftDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperSawtoothLeftDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.SawtoothLeftDistribution; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionSawtoothLeft; /** * Zusätzliche Daten für ein Objekt vom Typ {@link SawtoothLeftDistribution} @@ -126,4 +128,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((SawtoothLeftDistribution)distribution1).b-((SawtoothLeftDistribution)distribution2).b)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionSawtoothLeft.class; + } } \ No newline at end of file diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperSawtoothRightDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperSawtoothRightDistribution.java index bdc2361..865798c 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperSawtoothRightDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperSawtoothRightDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.SawtoothRightDistribution; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionSawtoothRight; /** * Zusätzliche Daten für ein Objekt vom Typ {@link SawtoothRightDistribution} @@ -126,4 +128,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((SawtoothRightDistribution)distribution1).b-((SawtoothRightDistribution)distribution2).b)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionSawtoothRight.class; + } } \ No newline at end of file diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperSineDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperSineDistribution.java new file mode 100644 index 0000000..9110935 --- /dev/null +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperSineDistribution.java @@ -0,0 +1,152 @@ +/** + * Copyright 2024 Alexander Herzog + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package mathtools.distribution.tools; + +import org.apache.commons.math3.distribution.AbstractRealDistribution; + +import mathtools.NumberTools; +import mathtools.distribution.SineDistribution; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionSine; + +/** + * Zusätzliche Daten für ein Objekt vom Typ {@link SineDistribution} + * @author Alexander Herzog + * @see SineDistribution + * @see DistributionTools + */ +public class WrapperSineDistribution extends AbstractDistributionWrapper { + /** + * Konstruktor der Klasse + */ + public WrapperSineDistribution() { + super(SineDistribution.class,true,false); + } + + @Override + protected String[] getNames() { + return DistributionTools.DistSine; + } + + @Override + protected String getThumbnailImageName() { + return "sine.png"; + } + + @Override + protected String getWikipediaURL() { + return DistributionTools.DistSineWikipedia; + } + + @Override + protected DistributionWrapperInfo getInfoInt(final AbstractRealDistribution distribution) { + return new DistributionWrapperInfo(distribution,0.0,distribution.getNumericalMean()); /* Schiefe=0 immer */ + } + + @Override + public AbstractRealDistribution getDistribution(final double mean, final double sd) { + /* + mean=(a+b)/2 + sd=sqrt(1/4-2/pi^2)*(b-a) + + a=2*mean-b + sd=sqrt(1/4-2/pi^2)*(2*b-2*mean) + + sd/sqrt(1/4-2/pi^2)/2+mean=b + */ + final double b=sd/Math.sqrt(1.0/4.0-2.0/Math.pow(Math.PI,2))/2.0+mean; + final double a=2.0*mean-b; + return new SineDistribution(a,b); + } + + @Override + public AbstractRealDistribution getDefaultDistribution() { + return getDistribution(50,100); + } + + @Override + public AbstractRealDistribution getDistributionForFit(final double mean, final double sd, final double min, final double max) { + return new SineDistribution(min,max); + } + + @Override + public double getMean(final AbstractRealDistribution distribution) { + return ((SineDistribution)distribution).getNumericalMean(); + } + + @Override + protected AbstractRealDistribution setMeanInt(final AbstractRealDistribution distribution, final double mean) { + final SineDistribution oldDistribution=(SineDistribution)distribution; + + final double delta=mean-oldDistribution.getNumericalMean(); + final double a=oldDistribution.getSupportLowerBound(); + final double b=oldDistribution.getSupportUpperBound(); + return new SineDistribution(a+delta,b+delta); + } + + @Override + public double getStandardDeviation(final AbstractRealDistribution distribution) { + return Math.sqrt(((SineDistribution)distribution).getNumericalVariance()); + } + + @Override + protected AbstractRealDistribution setStandardDeviationInt(final AbstractRealDistribution distribution, final double sd) { + return null; + } + + @Override + protected double getParameterInt(final AbstractRealDistribution distribution, final int nr) { + if (nr==1) return ((SineDistribution)distribution).getSupportLowerBound(); + if (nr==2) return ((SineDistribution)distribution).getSupportUpperBound(); + return 0.0; + } + + @Override + protected AbstractRealDistribution setParameterInt(final AbstractRealDistribution distribution, final int nr, final double value) { + if (nr==1) return new SineDistribution(value,((SineDistribution)distribution).getSupportUpperBound()); + if (nr==2) return new SineDistribution(((SineDistribution)distribution).getSupportLowerBound(),value); + return null; + } + + @Override + protected String getToStringData(final AbstractRealDistribution distribution) { + return NumberTools.formatSystemNumber(((SineDistribution)distribution).getSupportLowerBound())+";"+NumberTools.formatSystemNumber(((SineDistribution)distribution).getSupportUpperBound()); + } + + @Override + public AbstractRealDistribution fromString(final String data, final double maxXValue) { + final double[] values=getDoubleArray(data); + if (values.length!=2) return null; + return new SineDistribution(values[0],values[1]); + } + + @Override + protected AbstractRealDistribution cloneInt(final AbstractRealDistribution distribution) { + return new SineDistribution(((SineDistribution)distribution).getSupportLowerBound(),((SineDistribution)distribution).getSupportUpperBound()); + } + + @Override + protected boolean compareInt(final AbstractRealDistribution distribution1, final AbstractRealDistribution distribution2) { + if (Math.abs(((SineDistribution)distribution1).getSupportLowerBound()-((SineDistribution)distribution2).getSupportLowerBound())>DistributionTools.MAX_ERROR) return false; + if (Math.abs(((SineDistribution)distribution1).getSupportUpperBound()-((SineDistribution)distribution2).getSupportUpperBound())>DistributionTools.MAX_ERROR) return false; + return true; + } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionSine.class; + } +} diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperStudentTDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperStudentTDistribution.java index 1f94c59..12b1726 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperStudentTDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperStudentTDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.StudentTDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionStudentT; /** * Zusätzliche Daten für ein Objekt vom Typ {@link StudentTDistributionImpl} @@ -133,4 +135,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((StudentTDistributionImpl)distribution1).nu-((StudentTDistributionImpl)distribution2).nu)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionStudentT.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperTrapezoidDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperTrapezoidDistribution.java index a755d59..31aca0c 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperTrapezoidDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperTrapezoidDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.TrapezoidDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionTrapezoid; /** * Zusätzliche Daten für ein Objekt vom Typ {@link TrapezoidDistributionImpl} @@ -162,4 +164,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((TrapezoidDistributionImpl)distribution1).d-((TrapezoidDistributionImpl)distribution2).d)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionTrapezoid.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperTriangularDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperTriangularDistribution.java index 577e9f9..1398aaa 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperTriangularDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperTriangularDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.TriangularDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionTriangular; /** * Zusätzliche Daten für ein Objekt vom Typ {@link TriangularDistributionImpl} @@ -127,4 +129,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((TriangularDistributionImpl)distribution1).mostLikelyX-((TriangularDistributionImpl)distribution2).mostLikelyX)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionTriangular.class; + } } \ No newline at end of file diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperUQuadraticDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperUQuadraticDistribution.java new file mode 100644 index 0000000..1372ff5 --- /dev/null +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperUQuadraticDistribution.java @@ -0,0 +1,161 @@ +/** + * Copyright 2024 Alexander Herzog + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package mathtools.distribution.tools; + +import org.apache.commons.math3.distribution.AbstractRealDistribution; + +import mathtools.NumberTools; +import mathtools.distribution.UQuadraticDistribution; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionUQuadratic; + +/** + * Zusätzliche Daten für ein Objekt vom Typ {@link UQuadraticDistribution} + * @author Alexander Herzog + * @see UQuadraticDistribution + * @see DistributionTools + */ +public class WrapperUQuadraticDistribution extends AbstractDistributionWrapper { + /** + * Konstruktor der Klasse + */ + public WrapperUQuadraticDistribution() { + super(UQuadraticDistribution.class,true,true); + } + + @Override + protected String[] getNames() { + return DistributionTools.DistUQuadratic; + } + + @Override + protected String getThumbnailImageName() { + return "uquadratic.png"; + } + + @Override + protected String getWikipediaURL() { + return DistributionTools.DistUQuadraticWikipedia; + } + + @Override + protected DistributionWrapperInfo getInfoInt(final AbstractRealDistribution distribution) { + return new DistributionWrapperInfo(distribution,0.0,null); /* Schiefe=0 immer */ + } + + @Override + public AbstractRealDistribution getDistribution(final double mean, final double sd) { + /* + mean=(a+b)/2 + sd=sqrt(3/20)*(b-a) + + mean*2-a=b + sd*sqrt(20/3)+a=b + + a=mean-sd*sqrt(20/3)/2 + */ + final double a=mean-sd*Math.sqrt(20/3)/2; + double b=2*mean-a; + if (b<=a) b=b+0.01; + return new UQuadraticDistribution(a,b); + } + + @Override + public AbstractRealDistribution getDefaultDistribution() { + return getDistribution(100,50); + } + + @Override + public AbstractRealDistribution getDistributionForFit(final double mean, final double sd, final double min, final double max) { + if (sd<=0) return null; + return super.getDistributionForFit(mean,sd,min,max); + } + + @Override + public double getMean(final AbstractRealDistribution distribution) { + return ((UQuadraticDistribution)distribution).getNumericalMean(); + } + + @Override + protected AbstractRealDistribution setMeanInt(final AbstractRealDistribution distribution, final double mean) { + final UQuadraticDistribution oldDistribution=(UQuadraticDistribution)distribution; + + final double delta=mean-oldDistribution.getNumericalMean(); + final double a=oldDistribution.getSupportLowerBound(); + final double b=oldDistribution.getSupportUpperBound(); + return new UQuadraticDistribution(a+delta,b+delta); + } + + @Override + public double getStandardDeviation(final AbstractRealDistribution distribution) { + return Math.sqrt(((UQuadraticDistribution)distribution).getNumericalVariance()); + } + + @Override + protected AbstractRealDistribution setStandardDeviationInt(final AbstractRealDistribution distribution, final double sd) { + final UQuadraticDistribution oldDistribution=(UQuadraticDistribution)distribution; + + final double E=oldDistribution.getNumericalMean(); + final double var=sd*sd; + final double range=Math.sqrt(var*20/3); + final double newA=E-range/2; + final double newB=E+range/2; + return new UQuadraticDistribution(newA,newB); + } + + @Override + protected double getParameterInt(final AbstractRealDistribution distribution, final int nr) { + if (nr==1) return ((UQuadraticDistribution)distribution).getSupportLowerBound(); + if (nr==2) return ((UQuadraticDistribution)distribution).getSupportUpperBound(); + return 0.0; + } + + @Override + protected AbstractRealDistribution setParameterInt(final AbstractRealDistribution distribution, final int nr, final double value) { + if (nr==1) return new UQuadraticDistribution(value,((UQuadraticDistribution)distribution).getSupportUpperBound()); + if (nr==2) return new UQuadraticDistribution(((UQuadraticDistribution)distribution).getSupportLowerBound(),value); + return null; + } + + @Override + protected String getToStringData(final AbstractRealDistribution distribution) { + return NumberTools.formatSystemNumber(((UQuadraticDistribution)distribution).getSupportLowerBound())+";"+NumberTools.formatSystemNumber(((UQuadraticDistribution)distribution).getSupportUpperBound()); + } + + @Override + public AbstractRealDistribution fromString(final String data, final double maxXValue) { + final double[] values=getDoubleArray(data); + if (values.length!=2) return null; + return new UQuadraticDistribution(values[0],values[1]); + } + + @Override + protected AbstractRealDistribution cloneInt(final AbstractRealDistribution distribution) { + return new UQuadraticDistribution(((UQuadraticDistribution)distribution).getSupportLowerBound(),((UQuadraticDistribution)distribution).getSupportUpperBound()); + } + + @Override + protected boolean compareInt(final AbstractRealDistribution distribution1, final AbstractRealDistribution distribution2) { + if (Math.abs(((UQuadraticDistribution)distribution1).getSupportLowerBound()-((UQuadraticDistribution)distribution2).getSupportLowerBound())>DistributionTools.MAX_ERROR) return false; + if (Math.abs(((UQuadraticDistribution)distribution1).getSupportUpperBound()-((UQuadraticDistribution)distribution2).getSupportUpperBound())>DistributionTools.MAX_ERROR) return false; + return true; + } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionUQuadratic.class; + } +} diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperUniformRealDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperUniformRealDistribution.java index 3666c70..0199554 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperUniformRealDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperUniformRealDistribution.java @@ -19,6 +19,8 @@ import org.apache.commons.math3.distribution.UniformRealDistribution; import mathtools.NumberTools; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionUniform; /** * Zusätzliche Daten für ein Objekt vom Typ {@link UniformRealDistribution} @@ -142,4 +144,9 @@ protected boolean compareInt(final AbstractRealDistribution distribution1, final if (Math.abs(((UniformRealDistribution)distribution1).getSupportUpperBound()-((UniformRealDistribution)distribution2).getSupportUpperBound())>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionUniform.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperWeibullDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperWeibullDistribution.java index 0e02e05..2e2041c 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperWeibullDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperWeibullDistribution.java @@ -22,6 +22,8 @@ import mathtools.Functions; import mathtools.NumberTools; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDistributionWeibull; /** * Zusätzliche Daten für ein Objekt vom Typ {@link WeibullDistribution} @@ -146,4 +148,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((WeibullDistribution)distribution1).getScale()-((WeibullDistribution)distribution2).getScale())>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDistributionWeibull.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperZetaDistribution.java b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperZetaDistribution.java index b56a42f..453d9ad 100644 --- a/SimSystem/src/main/java/mathtools/distribution/tools/WrapperZetaDistribution.java +++ b/SimSystem/src/main/java/mathtools/distribution/tools/WrapperZetaDistribution.java @@ -19,6 +19,8 @@ import mathtools.NumberTools; import mathtools.distribution.DiscreteZetaDistributionImpl; +import parser.coresymbols.CalcSymbolPreOperator; +import parser.symbols.distributions.CalcSymbolDiscreteDistributionZeta; /** * Zusätzliche Daten für ein Objekt vom Typ {@link DiscreteZetaDistributionImpl} @@ -125,4 +127,9 @@ protected boolean compareInt(AbstractRealDistribution distribution1, AbstractRea if (Math.abs(((DiscreteZetaDistributionImpl)distribution1).s-((DiscreteZetaDistributionImpl)distribution2).s)>DistributionTools.MAX_ERROR) return false; return true; } + + @Override + protected Class getCalcSymbolClass() { + return CalcSymbolDiscreteDistributionZeta.class; + } } diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/res/arcsine.png b/SimSystem/src/main/java/mathtools/distribution/tools/res/arcsine.png new file mode 100644 index 0000000000000000000000000000000000000000..ae32461cb58b16b76a3c9fd4b8fef7125b4e4a46 GIT binary patch literal 28633 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 E2Lsli{Qv*} literal 0 HcmV?d00001 diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/res/chi.png b/SimSystem/src/main/java/mathtools/distribution/tools/res/chi.png index 580a8e2cacb7068bde7fd328ee174d69917eb077..0ccc1f620386986d4e1352fed6443dc0b4a7f813 100644 GIT binary patch delta 9528 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 delta 7113 zcmYLuWmwc-)GZy-(t=1hh;)ZApmc|HNjF1C3&Rf(NokO7qEooB7RcAZaW?}k;>?P1i|WK|iL&pNu^8AoIKBq+pWD4lZVxR~m)=yI46)+sA! zOR`5Ad7~UC|Mzez4xQZGKlpd7o!pqj$2?r2|3CaR3=`ynD{pjiNS|Pissm6vK^(L+ z|M@gta9fg17}$;6l5gL%WV^5CDqUP$Ec%Q7{`AW>Lqx>ea8#CCZ`ZS+KCX!EBumgI zipQIy*^0jNG794DnIg2na zf!LBlN}-b>i$27-6o3ktJ>8hWj9f$B2+-xAQjdVV`9?v$lf)s5l zjhIS=!Fz}SVQWMGC)G1L2n}O{ug6?>K-md4ywi}fd=a+16}J3^uIUQ-IVN>E#NaCW z!oQ|`M$E=Lpog{xK&|0(gi(Y#hoV2GLM|AtgP9u8^`h$47J2H7?Ju;p)PoB4Q0(4~ z5&W*}dS9BNaiQLA8E}dMckf>Bu0Z3YiZK(U7XL+xh43X*Pj9uzRS^+W6A^<7`>Pi6 z2h75&Fx64fN|d!%6HH}%q@g6FGgw4-_yg9d?r~D<4t%>n6dt?#K|l&8)q{Y$!>`%l zMeQ^I)htSKks!FO(9LsBL#qC?lCd|#OucnZ{57faDyLrHb3=zEoDMctre1kQQ zYYA9$IV4HaMcRrX&_)J74Tq2?hMP7zf{KukEKs`o5y$L9tQ zrb?&nYB|BOWBDM{nU~R~(EIRYMg4>LyPtz8Kk(LnlGu&W{P7dU#iK;}ItWNcJ&=rvycyFDHXE?GUh_AInA0^76;5h>Zid3Ow* zp`PgiDe~`@^o7>0RTr@8(xCv;umWnmd2eN1KtBjUyyl-PT&w6$r!w)j%E+}gb)bF} zE2c4V$XbMwiE26ZSG-%?*GpXT&xy+jvFoi9y?d~Q)1v7-Keb?@WN`IVRb*6OwV8De z2KIqnSad4U%Z~RlV?qzRB3Qv^0A0q09zw(E`{>_o@=nOs&m6;DvT^|&s#cvm$)4f zrl@y$@(Y0-A!ngSXQ1xn8&6`^UqvtbgZ>>OQ`etkw99c@~TKl(ZBi=5cfte@?!yuDb3cc2j2X$N?Clm>=5o- zJPlqg7F-N`p|pWX*Ec^VicxMA0I=1j%&{N4j!9hKXAPl=_>~&1(w)D02{_^Uaq*cZ zz1Ah!W5k~wRSl7RjB+^r`v=r=hXhU28EV4&8ov^GZc6&yk~FsBA|Cyl6HfMtRB7>K z->vNr+PLZR1>sVHg3SlSaTYShW6MAo82fQP{;w~_z@s6b7gd`s2{u^@0XlLXo2uP_ zI30r56?`mMigC2VJIXt zh`{&`tbWWougRZ>e0)u*XdEmRR%{RcLq9=MTCkuPsd@N8U7Vr|zwx2{m*gS+XWXl8 z%k3bseE_wE2ZXs#p<{d{qKztO-6g@FG*k|148oo_6=08_NzKHa1_np(7|(Rrt%t8W zy@J)>iOOwhR~At>5gotQC^4pbf~j6tUQHUwH&Ztyxe zMp&G@qD7LRJSo3Al_duUq>LkEAEl z5@(^Jwcsx6DvwUW15olRCuZO7&5z*Sn!Tl3WW6>Uz3k(k>}-5pd!KCaOPN__&pY!y z`NP;y^~)E%Y!>>aZI?`NT#hIf19S~tqAF*BOBP`*4C=CkHlN{wMDCggMOhXnCC#AL zad(sfu9D)6`jk`VjFL2flQrwVZbrj+sI33h(7 zWh{i`@G+r=_aOr3T{kbju`6eVa^FTWFBflA`~m?Zb`z z0$x?SC$33owQ(?=W{aOEWArO#+P#$P6fN*>3Yb~h8A!*kwDH;}Te5~gzoWLj1ckzH87FSYJp(kiv0{9Y14o4OWt-^w(eU!&e^F#umb|DpQS zs-D1*_Ls(B{+e*<^5DjzeEyqlH}Fh=U?{dIH))fT$b9p!S@+q@v=-M)T}0ZK;K9)W zsbVH!e;~!hPe4FGQGi?n&R1CoY0tYR)mY$A>4OoIcJi~Wk5)3sG~Vst~JXVcR&C( z&m3UXbwP4({I$1FOSWgtD^!snx{M_AA8y~@1N=4`dJ-FEw031>FQ1S=R*EGu?iNrjkL@S<$@G2cQ~WdT`*gjlrv1Ve&TgUId^(KrBIg3i2bv&#Aj@I zK=qz~C2!~v2pocBDLHDYqMZ>56&cr8N!t3DR2D4X5CM8uL2Aam=$Z1nA#J$)qg5*F zg=aCD{$^q{ToL7g7!ARfVFeF@dtG*>fVqiGOIZeHr?0}P>CzudU*M!L-zQ>mn*FVJ z`fP~Ok%&V0fh`*J0m(|$D=jpz_4?KZ;N+L1Nk302;a)q9a>DzwM{DnxI;nJ;T<30p z)l^8Q`!leeielUmqr%$FD5k++CdcDrLRH02V*|CO=~%hfWyg;MPYw9yOqRrYOx;c9 zrdU7h`Nx{I`Cele|0U#36)2pswdirKP#J5|(0s=0Ws|VaUOBu(-3=K?gBZk00~6ME z6=Q@Iw!vk!e$&%zaKwDKtdnw@hef>QcK`C{3j3hAx&Dh1r`Oaztrk*r8l11%;5{82 z`SaVdBzIWPY)7~;h?{iEKnx3$G|i(nsPXkLl$sOeH@|rZ;VO7;1uN$hKJD-ai-M6$ zf*3yn`|}$QFB%fI%mgz7_Kv!!k;CRo=ZQ6fm?t z?G^f}*2)}e!v0szlRbi_o!aTUs}HxSTSmOs2q${@r<5VmqE^~(eu0R}XyBotghCfL zYbx(n=_sHh6Uie=m#P9af-ry6vnutD@^`{}t)YG4VD|yaA!<6ZujHq7i{_c-@054< zYvte*N26~p=!093UGi+|rdT0CM-`$B-a8!M^d#P;*K*kqIzCgow9s!-mHPmgK3=p4 z23}+8Q=$2c2Z{x-snu~I0nn*LK*YHG%RLuIL$`fnrGi2!VIaG0al=DYPTHg^tU=P^ zT++**WZ#1Fxl_XnijK$A-jjVpRp`ZFy&B`(@l>PCp}n#H7~r5(p;{p@7VyfLuinHI zcqZpU6f=f6SfX($C**kdptV2x4k?&}Dd7{>;)D^8!e|nkcKh-PP=PbqIE9S+NjbY3 z*$*I>on55kVAi4NXz!;%5afCRt0;wyr>05=XV3dDzqjW+GTG_- ziJrYR_S!Jf2sb)QY=`Zl9Ww3v-4b@)thnFmVtlt_DC*pQRX{*pw$2I!=U%YIZ_{w6 zk+SBE^3|O(y6@5f;PK`H%y*7aS4}_?gK^&~Te!F8dog6`z#@S9$k~{IfM&zf8-eoz zst0F^7Ju~0IVlP9v83w51j@pj^$`DUx-4~~H_OS|TSUej#`}|H27K|79#*#7JlWQ3 zTX;HX8NAHdBk^D-62gV^?40oMYp&fLO*+UXIRhFaY-l;dFwRNcY>B`g zo#dVS@t^*PudX}G$!EuyJFf#RVMbBED-GL;V#vQhMn1a#)n|tfZPZy! z$}s-y`Je7zQWuspjWz$z>3_2Snt}R7{0$p^?jOLJ(E_nf1n~>YsOM~;U|Nn?hC&^| zSpE+76v)w>j{c}>k7n`_LE#^@En|Z-`UmAbd$m=R0O5RJ{4WMSr}(iM&DY^>mYBrF z6b;}r>0mcsI|m0?eVW!olZc@MS%bi+?5Km`lA9C6>^d1Xb<)&kHik0q3!%8-|HU+K zWE)H*Oj98*n2-@Q3|qWUj~xEI?8#|R$=4p!RLpRDEj1()$<6=hF^Z{BPZ#1(v8<8) z01-9-#)XukIsbdO4!5>-o;_RtZ(4l>PhAIBr{|52@^qYdhE4k3_013nCY|83^HU*u zXgx9MfDIHxnQVmg+BI*=%iT5C;5$g5wE+>WG12{~YQhs^ubSr2|7E!mI?x@p%$=NcXI=xKKlFBd0+gsxc5yxa z)~q9EIBF1l%cVh>CntQ%MJ}uO^Y?sL9pv#Q$o(;j+ezv=0>4+ydP@mLS1bAQ#=v_~ zdIgO`^qXd))7yMOg;9~bIogY5<}Wi6+;b7Gli!8+c=s~1zKu@+$pp4?wAIgBuR1(C0v36Vzc`3$=KXBGwUiA9ihGOhX*l(W9zOkZEz!}sn?Y}V!l$?EO!V)*= z*7$~mfAc2p!d!rnH0t4l{T0HJ_A5XlTcsIwl8P2}*#g!zkAoJC;XFSF=LsX<^u`Eg z>^y%}L%WX7Jt0zqGtTakkt}X#7JMhs(I`iz)^O_8h4YQ1KgctAw*pIs1-;+CZ?}$M zIEOpW^mPxF;MXVD=&9+}Aod5o!7s-X6W%%n51QlUb-I6H%*UL9g~eW~WV(QV&gzt+ z+5;`mv6W`YjhODrj|#2#2gOIYJ1p#>c0n9eagJC^Qznx-yOwM!Y1tE<5--XhH3oGA zzcNh@ySG=`cigQWjJ&c5PLmP&ow&9f9j%pNyQ^B(wEOY#FN^DJWtxT< z)}{E=cbXbx{72UX9BuN+AR7%poTK1^Kse~oU#7iIl|p?*WOzSuCAK5e4)1&g&)Ehi z?+9N`cck$v;iDPC%W(^HVAMY8W#3D#**D@l9Yf;TSaCP9_fW>o`KaqJLR64rK7*Yy z-bJMfHJnG%T?sw4JLQJ(-)8K3MfH2s3ez8BnvP-lWV_{O;ul7@=rfc+q#V4+r4Kh# z^h#gU{>>lOwUz4jRA=a}ZhiYnw{vmj(0JZWE8hGBi%Da#1e4rgFtZ?eJPw4IR+&7wzuLvgb1n+8{bqVAG3#6e|80IC0!}Bj9+p2*KOF z4X)o8sBya%J`U31{-^`23t7`y{2nH2plIVFn^jE8GASqr1}BG^bA5;Bz%X*$gVOb~ z6DZ}Rmz{CA>N^))JId>_TpNXVxiNf?Nb$3ZC!sv;@|mLO9PFcXXxt zMqRX5<9Jqyv(3Ky22VGyvZ}A#9&b4LgO-6w&-LaB{%oU3*bu<+D#l}Xb72c7|K^0O zs>dd>7^>>?au$nne%$woMBPV5EDovJLTV5r>$4Jbp5$Qnzyp-}sj}6nK4?cwd~69QEa&u_^V83%f?h@p2VL3l>C7XV#;?N!w$qMrSo$Z*IYWG z<(1)-0po8g_5e!`!^gz}4_=d5miBfX|Ga1B+(AVAM9n$QslRYJRSqORbs@3%HV3aH zij08N3y%7{v)Sfc?|Y`5QIj0Xa=#jFGZWLbO*d2{QrOrLPiq!o{wu?!CRIaanl5A0 zP-;_W^|8jT?3(5}UdQJf`!B{CSQ9HYov*1IRU#_prhq9dpFI)Z_@-TZE95xQhc|rh zJYQzE=D3Czy)_JAXN>q&dxgtYrXu?bD0+V;8X0X`?+ee_1yP!Ny+`D$-V|tS;H;pk?Uq&e4Cf-2~8bZhc2i z6iiQNm!N88#h6{C>fdy?C*XglyOBRp)5Rf+=|A7g2AbT$1X2hi>6^uwCRdFw{tTmGf2^OCL-^D$G3Kd%=Ulgh+|V-0_e^9RAo z!Nt*_50Mw@rEE*Us%>M7o&o7fnzAkR00MFn^5wi?jj-xRTN?@5EcHCgqRac|goXvH zsAi(Q%m|3EWY{_rinDjcMgW9%vF@EC{AUz;+vvt9=ckUZ&_AnHJ!=#rtWGb1>$3nz z2+pLcGo?_+JMVF-hNZ(ToR<3;yRD*CQ~4DUbR@qEp)1@fJrLeE_9*&dtkYFJ;xWv9 z@>LXPZ==}QklIrLhqiB9BlyMm68Ocz;A(m`o9jixQuo+nmPdWCNuO>+4(q;@pA9gr@tV6+HvH!fRco%1b>!Djj#=%@{h>E@c!) zuF&LuwQH5spqH1z>^O?CBhCGOYya+1*Xqn?;Xgf9zriOk--aWG+s&}$A}{Xl+{Jqr zo%%do{QUhW!qw&x6IOwFpU^UBNG4rc@8m{kD4}R8hqyCr0({mqAl?XUT=xjZc2&X| zDn!uVi67?FhCph92fcT=7=pkrA~fuRXoQW0ty}G<%Rb$M-DmyR7*y(3(WAUe>B{fQ z6u}57-A~xMo-Vewg?_f?%2HP;Ar0uEt@#kL^&~T$wqu3`S?>9-&^%UcN^@Q zWsUW)-j1;Ikc*6FUy-vNbd}Tm&IZd4tLo~=H=evBiG&ir-~2Vkz7?-qS2ye)>U8p#{{gq_`SVoaayE&p$U(*kjj{I{$zRvmfP%}qQywsuMy zZ~jV`<{oFIxQ^V=`HBRg%|Ji$*rITNzC3a`ddQw%Hf{cCgap%rp5XHz8{yKZF8c4q zS`{Biu(fQWKEwcHX71Q_8y|PU7+}3%4`-f=2pEh=z&oJApWcw$6y3L$rUeEfEl3|q zT$kj%P|){bK!<4Tcbhkk6!G#QwU@jqx%RZ~tbVC4WymTE*AKVZ&sg`)#NyETSTWX6 zk0!tNBS(heRN+E*G1Wd9>QXIbD59XS()_DK>u!Ab5eK7Msrp}Gs0pYLDOeZN=v%UM z2u=+O3gO)UH^C?-HciM?k%Mung%Og4NGqhEpggPpAGYZ3^#8IXpRAvedHq@}MM1%^ z{vWm&gZ>{Y4};rMV356eHoE>V)QA6N$>;ymCP+ihEr)h?QvW3)uOR(F>)$$TDv$t$ zp18ZS{r=>;Qc75%5Gp|ehBexIUNQR>I+q9r2)><#JdM;M)$jgT!H_zhf~fzX3zb2X fCh%skGu^@|1e*h1F;D!@CyIiMs&u8KY0&=xFbVP- diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/res/chisquare.png b/SimSystem/src/main/java/mathtools/distribution/tools/res/chisquare.png index 33c75015a13fe30b9d71198c595610aa0819fe2b..11cf743648e93804287b813d7754afa4a3e71650 100644 GIT binary patch delta 8746 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 delta 7804 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 literal 0 HcmV?d00001 diff --git a/SimSystem/src/main/java/mathtools/distribution/tools/res/sine.png b/SimSystem/src/main/java/mathtools/distribution/tools/res/sine.png new file mode 100644 index 0000000000000000000000000000000000000000..7e510f59397034c1fa2b322d35cff5ab296fa709 GIT binary patch literal 29183 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

w{CG`wkl-sx1tV0!?#-}(JN|pF8jdH3LOQJNu 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 z mX<_@r-|nF#oXYXKn9XzcrREy=MYJ4Y7ay7XxjqMZ0q;xcxkRDeFZ7ox*asZq z*{`D#<5`}$(dnx2e$y*FtB*_Kc|_3~DOSvZLk06ov-H!;(z$@-F?~0;n&(YAILhL^ z{p)#lq&qP4&|IF<80Lg?G18~kw0cd3Z#~-scY^F}pE%d0e!V@qbqq}&EFR#g*6%mJ zA!mMJK*EAtS~U8_#^$AExu4+bPB0ffSplr*7Wh&!!M#f7g2;ax@zLsuC2`ov@+ETH z3BIT~FSu>th`t8XNT;ID-f16=DcC0KgvYX9&deB-`^JRm3Di6BN0jS#BpcbkfI*lV zo?7z)_!E9zR_yg@BFP}QpuxPW1ghN$v^%AoZT+VDTT)Q5K`=|?qN=-0xmspKd|`!uWpn*is(U)4RiU)^0-t)NoiY*Y-GFJvOO z1c z1xKi&8N`*qCEMlshrjZzl7sdef}S(4zL1*3)V($X1# zcy^9*f$gv&t{^g4_mS61S$ebiyNRW8YN|82@^o-`$d9*O=SdmK9y)rHR_TVqe@VHz zPYsRdyXAq>P9?#;KIZ@eRM;&16fatj&EgE0!#g=7Eu#pi??vGaa(9r6@dgrL}{UShzJ;J zLJ>j_Jp=-QBqXGNocrGM-n-WQ8`Ywf*e&&--2-5ogxx!0LusKGM=BI-gyR2`lEC>2F2MD1nm+=XbQ40-jMdeAncOT;))*7>L|*nt(IYdLyvGLvub-