Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/fitting/LinearRegressionSqrtErrorFunction.java @ 9646:0380717105ba
Implemented alternative fitting strategy for Log-Linear function.
author | Gernot Belger <g.belger@bjoernsen.de> |
---|---|
date | Mon, 02 Dec 2019 17:56:15 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
9645:eb1a29fe823f | 9646:0380717105ba |
---|---|
1 /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde | |
2 * Software engineering by | |
3 * Björnsen Beratende Ingenieure GmbH | |
4 * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt | |
5 * | |
6 * This file is Free Software under the GNU AGPL (>=v3) | |
7 * and comes with ABSOLUTELY NO WARRANTY! Check out the | |
8 * documentation coming with Dive4Elements River for details. | |
9 */ | |
10 package org.dive4elements.river.artifacts.model.fixings.fitting; | |
11 | |
12 import org.apache.commons.math3.analysis.MultivariateFunction; | |
13 import org.apache.commons.math3.analysis.UnivariateFunction; | |
14 import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; | |
15 import org.apache.commons.math3.stat.regression.SimpleRegression; | |
16 | |
17 /** | |
18 * @author Gernot Belger | |
19 * | |
20 */ | |
21 final class LinearRegressionSqrtErrorFunction implements MultivariateFunction, UnivariateFunction { | |
22 | |
23 private final double[] obsDischarges; | |
24 | |
25 private final double[] obsWaterlevels; | |
26 | |
27 private final double waterlevelMean; | |
28 | |
29 private final double waterlevelDeviation; | |
30 | |
31 private final double[] standardizedWaterlevel; | |
32 | |
33 private final SQRTFunction sqrtFunction; | |
34 | |
35 private final TargetFunction targetFunction; | |
36 | |
37 public LinearRegressionSqrtErrorFunction(final double[] obsDischarges, final double[] obsWaterlevels, final TargetFunction targetFunction) { | |
38 | |
39 this.obsDischarges = obsDischarges; | |
40 this.obsWaterlevels = obsWaterlevels; | |
41 | |
42 this.sqrtFunction = new SQRTFunction(obsWaterlevels); | |
43 this.targetFunction = targetFunction; | |
44 | |
45 final DescriptiveStatistics stats = new DescriptiveStatistics(obsWaterlevels); | |
46 | |
47 // Compute mean and standard deviation | |
48 this.waterlevelMean = stats.getMean(); | |
49 this.waterlevelDeviation = stats.getStandardDeviation(); | |
50 // -mittelwert durch standardabweichung /z-transformation) | |
51 | |
52 // initialize the standardizedSample, which has the same length as the sample | |
53 this.standardizedWaterlevel = new double[obsWaterlevels.length]; | |
54 | |
55 for (int i = 0; i < obsWaterlevels.length; i++) | |
56 this.standardizedWaterlevel[i] = (obsWaterlevels[i] - this.waterlevelMean) / this.waterlevelDeviation; | |
57 } | |
58 | |
59 @Override | |
60 public double value(final double[] point) { | |
61 | |
62 final double a = point[0]; | |
63 | |
64 return value(a); | |
65 } | |
66 | |
67 @Override | |
68 public double value(final double a) { | |
69 | |
70 final double error = calc_sqrt_trans(a); | |
71 if (Double.isNaN(error)) | |
72 return Double.POSITIVE_INFINITY; | |
73 | |
74 return error; | |
75 } | |
76 | |
77 private double calc_sqrt_trans(final double a) { | |
78 | |
79 final double[] waterlevels = calc_stage_trans(a); | |
80 | |
81 return this.sqrtFunction.calc_sqrt(waterlevels); | |
82 } | |
83 | |
84 private double[] calc_stage_trans(final double a) { | |
85 | |
86 final double[] params = calc_parameters_trans(a); | |
87 | |
88 final double b = params[0]; | |
89 final double m = params[1]; | |
90 | |
91 return this.targetFunction.calc_stages(a, b, m); | |
92 } | |
93 | |
94 public double[] calc_parameters_trans(final double a) { | |
95 | |
96 // stages_obs_trans = trans_stages(stages_obs, parameter_a); | |
97 final double[] transWaterlevels = trans_stages(this.obsWaterlevels, a); | |
98 final double[] discharges = this.obsDischarges; | |
99 | |
100 // FIXME: z-nromalizing? | |
101 | |
102 // printArray(discharges); | |
103 // printArray(transWaterlevels); | |
104 | |
105 // final DescriptiveStatistics stats = new DescriptiveStatistics(transWaterlevels); | |
106 // | |
107 // // Compute mean and standard deviation | |
108 // final double mean = stats.getMean(); | |
109 // final double deviation = stats.getStandardDeviation(); | |
110 // | |
111 // final double[] normWaterlevel = new double[transWaterlevels.length]; | |
112 // for (int i = 0; i < transWaterlevels.length; i++) | |
113 // normWaterlevel[i] = (transWaterlevels[i] - mean) / deviation; | |
114 | |
115 final SimpleRegression regression = new SimpleRegression(true); | |
116 for (int i = 0; i < discharges.length; i++) | |
117 regression.addData(discharges[i], transWaterlevels[i]); | |
118 | |
119 final double normSlope = regression.getSlope(); | |
120 final double normIntercept = regression.getIntercept(); | |
121 | |
122 // unnormalize | |
123 // final double slope = normSlope * deviation; | |
124 // final double intercept = normIntercept + mean; | |
125 final double slope = normSlope; | |
126 final double intercept = normIntercept; | |
127 | |
128 return new double[] { intercept, slope }; | |
129 } | |
130 | |
131 // private void printArray(final double[] discharges) { | |
132 // for (final double d : discharges) { | |
133 // System.out.print(d); | |
134 // System.out.print(", "); | |
135 // } | |
136 // System.out.println(" "); | |
137 // } | |
138 | |
139 private double[] trans_stages(final double[] waterlevels, final double a) { | |
140 | |
141 final double[] transWaterlevels = new double[waterlevels.length]; | |
142 for (int i = 0; i < transWaterlevels.length; i++) | |
143 transWaterlevels[i] = Math.exp(waterlevels[i] / a); | |
144 | |
145 return transWaterlevels; | |
146 } | |
147 } |