TAChart: Handle numerical overflows during fitting by catching the exception.

git-svn-id: trunk@63618 -
This commit is contained in:
wp 2020-07-22 08:09:47 +00:00
parent 6c06094f0f
commit 39e235c21c
15 changed files with 73 additions and 25 deletions

View File

@ -215,6 +215,10 @@ msgstr "Die Anzahl der Fitparameter kann nicht kleiner als 1 sein."
msgid "Expression result type must be integer or float. Got \"%s\"."
msgstr "Der Typ des Ausdrucksergebnisses muss integer oder float sein, ist aber \"%s\"."
#: tachartstrconsts.rserrnumericaloverflow
msgid "Numerical overflow."
msgstr ""
#: tachartstrconsts.rsexpressioncolormapseries
msgid "Math expression color map series"
msgstr "Math. Funktion (farb-kodiert)"

View File

@ -203,6 +203,10 @@ msgstr ""
msgid "Expression result type must be integer or float. Got \"%s\"."
msgstr ""
#: tachartstrconsts.rserrnumericaloverflow
msgid "Numerical overflow."
msgstr ""
#: tachartstrconsts.rsexpressioncolormapseries
msgid "Math expression color map series"
msgstr ""

View File

@ -213,6 +213,10 @@ msgstr "Le nombre de paramètres appropriés ne peut pas être inférieur à 1."
msgid "Expression result type must be integer or float. Got \"%s\"."
msgstr "Le type de résultat d'expression doit être entier ou flottant. On a obtenu \"%s\"."
#: tachartstrconsts.rserrnumericaloverflow
msgid "Numerical overflow."
msgstr ""
#: tachartstrconsts.rsexpressioncolormapseries
msgid "Math expression color map series"
msgstr "Séries de cartes de couleurs d'expressions mathématiques"

View File

@ -213,6 +213,10 @@ msgstr ""
msgid "Expression result type must be integer or float. Got \"%s\"."
msgstr "A kifejezés típusának egész vagy lebegőpontos számnak kell lennie. Most \"%s\"."
#: tachartstrconsts.rserrnumericaloverflow
msgid "Numerical overflow."
msgstr ""
#: tachartstrconsts.rsexpressioncolormapseries
msgid "Math expression color map series"
msgstr "Színtérkép matematikai kifejezés alapján"

View File

@ -214,6 +214,10 @@ msgstr ""
msgid "Expression result type must be integer or float. Got \"%s\"."
msgstr ""
#: tachartstrconsts.rserrnumericaloverflow
msgid "Numerical overflow."
msgstr ""
#: tachartstrconsts.rsexpressioncolormapseries
msgid "Math expression color map series"
msgstr ""

View File

@ -213,6 +213,10 @@ msgstr ""
msgid "Expression result type must be integer or float. Got \"%s\"."
msgstr ""
#: tachartstrconsts.rserrnumericaloverflow
msgid "Numerical overflow."
msgstr ""
#: tachartstrconsts.rsexpressioncolormapseries
msgid "Math expression color map series"
msgstr ""

View File

@ -203,6 +203,10 @@ msgstr ""
msgid "Expression result type must be integer or float. Got \"%s\"."
msgstr ""
#: tachartstrconsts.rserrnumericaloverflow
msgid "Numerical overflow."
msgstr ""
#: tachartstrconsts.rsexpressioncolormapseries
msgid "Math expression color map series"
msgstr ""

View File

@ -213,6 +213,10 @@ msgstr "O número de parâmetros à preencher não pode ser menor que 1."
msgid "Expression result type must be integer or float. Got \"%s\"."
msgstr "Tipo de resultado da expressão deve ser inteiro ou flutuante. Obtido \"%s\"."
#: tachartstrconsts.rserrnumericaloverflow
msgid "Numerical overflow."
msgstr ""
#: tachartstrconsts.rsexpressioncolormapseries
msgid "Math expression color map series"
msgstr "Série Mapa de cor de expressão matemática"

View File

@ -213,6 +213,10 @@ msgstr "Независимых переменных не может быть м
msgid "Expression result type must be integer or float. Got \"%s\"."
msgstr "Тип результата выражения должен быть целым либо вещественным, но сейчас является \"%s\"."
#: tachartstrconsts.rserrnumericaloverflow
msgid "Numerical overflow."
msgstr ""
#: tachartstrconsts.rsexpressioncolormapseries
msgid "Math expression color map series"
msgstr "Диаграмма с картой цветов по математическому выражению"

View File

@ -216,6 +216,10 @@ msgstr ""
msgid "Expression result type must be integer or float. Got \"%s\"."
msgstr ""
#: tachartstrconsts.rserrnumericaloverflow
msgid "Numerical overflow."
msgstr ""
#: tachartstrconsts.rsexpressioncolormapseries
msgid "Math expression color map series"
msgstr ""

View File

@ -216,6 +216,10 @@ msgstr "Число параметрів апроксимації не може
msgid "Expression result type must be integer or float. Got \"%s\"."
msgstr "Тип значення виразу повинен бути цілим або дійсним. Отримано \"%s\"."
#: tachartstrconsts.rserrnumericaloverflow
msgid "Numerical overflow."
msgstr ""
#: tachartstrconsts.rsexpressioncolormapseries
msgid "Math expression color map series"
msgstr "Колірна карта"

View File

@ -214,6 +214,10 @@ msgstr ""
msgid "Expression result type must be integer or float. Got \"%s\"."
msgstr "表达式结果类型必须是整型(integer)或浮点型(float).得到\"%s\"."
#: tachartstrconsts.rserrnumericaloverflow
msgid "Numerical overflow."
msgstr ""
#: tachartstrconsts.rsexpressioncolormapseries
msgid "Math expression color map series"
msgstr "数学表达式彩色图系列"

View File

@ -148,6 +148,7 @@ resourcestring
rsErrFitNoFitParams = 'No fit parameters specified.';
rsErrFitSingular = 'Fitting matrix is (nearly) singular.';
rsErrFitNoBaseFunctions = 'Not enough user-provided base functions.';
rsErrNumericalOverflow = 'Numerical overflow.';
rsFitNumObservations = 'Number of observations';
rsFitNumFitParams = 'Number of fit parameters';
rsFitDegreesOfFreedom = 'Degrees of freedom';

View File

@ -35,7 +35,8 @@ type
fitMoreParamsThanValues, // There are more fitting parameters than data values
fitNoFitParams, // No fit parameters specified
fitSingular, // Matrix is (nearly) singular
fitNoBaseFunctions // No user-provided base functions
fitNoBaseFunctions, // No user-provided base functions
fitOverflow // Numerical overflow
);
TFitResults = record
@ -201,9 +202,6 @@ end;
- Numerical Recipes, Ch 14, Modelling of data, General linear least squares }
function LinearFit(const x, y, dy: TArbFloatArray;
FitParams: TFitParamArray): TFitResults;
const
TOO_LARGE = 1E100;
TOO_SMALL = 1.0 / TOO_LARGE;
var
alpha: TArbFloatArray = nil;
beta: TArbFloatArray = nil;
@ -297,11 +295,6 @@ begin
kj := k * mfit + j;
jk := j * mfit + k;
alpha[kj] := alpha[jk];
if not InRange(abs(alpha[kj]), TOO_SMALL, TOO_LARGE) then
begin
Result.ErrCode := fitSingular;
exit;
end;
end;
// Solve equation system

View File

@ -1821,6 +1821,7 @@ begin
fitNoFitParams : Result := rsErrFitNoFitParams;
fitSingular : Result := rsErrFitSingular;
fitNoBaseFunctions : Result := rsErrFitNoBaseFunctions;
fitOverflow : Result := rsErrNumericalOverflow;
else
raise EChartError.CreateFmt('[%s.ErrorMsg] No message text assigned to error code #%d.',
[NameOrClassName(self), ord(ErrCode)]);
@ -1885,25 +1886,30 @@ var
end;
// Execute the polynomial fit; the degree of the polynomial is np - 1.
fitRes := LinearFit(xv, yv, dy, FFitParams);
FErrCode := fitRes.ErrCode;
if fitRes.ErrCode <> fitOK then
exit;
try
fitRes := LinearFit(xv, yv, dy, FFitParams);
// Store values of fit parameters.
// Note: In case of exponential and power fit equations, the first fitted
// parameter is the logarithm of the "real" parameter. It needs to be
// transformed back to real units by exp function. This is done by the
// getter of the property
for i:= 0 to High(FFitParams) do
FFitParams[i].Value := fitRes.ParamValues[i];
FErrCode := fitRes.ErrCode;
if fitRes.ErrCode <> fitOK then
exit;
// Analysis of variance, variance-covariance matrix
FFitStatistics.Free;
FFitStatistics := TFitStatistics.Create(fitRes, 1 - FConfidenceLevel);
// Store values of fit parameters.
// Note: In case of exponential and power fit equations, the first fitted
// parameter is the logarithm of the "real" parameter. It needs to be
// transformed back to real units by exp function. This is done by the
// getter of the property
for i:= 0 to High(FFitParams) do
FFitParams[i].Value := fitRes.ParamValues[i];
// State of the fit
FState := fpsValid;
// Analysis of variance, variance-covariance matrix
FFitStatistics.Free;
FFitStatistics := TFitStatistics.Create(fitRes, 1 - FConfidenceLevel);
// State of the fit
FState := fpsValid;
except
FErrCode := fitOverflow;
end;
end;
begin