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 }

http://dive4elements.wald.intevation.org