Browse Source

Cleanups

pull/769/head
Christoph Ruegg 5 years ago
parent
commit
59a9933531
  1. 6
      MathNet.Numerics.sln.DotSettings
  2. 2
      src/NativeProviders/Windows/MKL/MKLWrapper.vcxproj
  3. 6
      src/Numerics.Tests/DistributionTests/Continuous/BurrTests.cs
  4. 2
      src/Numerics.Tests/DistributionTests/Continuous/InverseGaussianTests.cs
  5. 2
      src/Numerics.Tests/DistributionTests/Continuous/TruncatedParetoTests.cs
  6. 3
      src/Numerics.Tests/DistributionTests/Discrete/CategoricalTests.cs
  7. 3
      src/Numerics.Tests/DistributionTests/Multivariate/MultinomialTests.cs
  8. 3
      src/Numerics.Tests/FinancialTests/CompoundReturnTests.cs
  9. 3
      src/Numerics.Tests/FinancialTests/DownsideDeviationTests.cs
  10. 3
      src/Numerics.Tests/FinancialTests/GainLossRatioTests.cs
  11. 3
      src/Numerics.Tests/FinancialTests/GainMeanTests.cs
  12. 3
      src/Numerics.Tests/FinancialTests/GainStandardDeviationTests.cs
  13. 3
      src/Numerics.Tests/FinancialTests/LossMeanTests.cs
  14. 3
      src/Numerics.Tests/FinancialTests/LossStandardDeviationTests.cs
  15. 3
      src/Numerics.Tests/FinancialTests/SemiDeviationTests.cs
  16. 4
      src/Numerics.Tests/LinearAlgebraTests/Complex/Solvers/StopCriterion/IterationCountStopCriteriumTest.cs
  17. 4
      src/Numerics.Tests/LinearAlgebraTests/Complex32/Solvers/StopCriterion/IterationCountStopCriteriumTest.cs
  18. 4
      src/Numerics.Tests/LinearAlgebraTests/Double/Solvers/StopCriterion/IterationCountStopCriteriumTest.cs
  19. 1
      src/Numerics.Tests/LinearAlgebraTests/Double/Solvers/StopCriterion/ResidualStopCriteriumTest.cs
  20. 4
      src/Numerics.Tests/LinearAlgebraTests/Single/Solvers/StopCriterion/IterationCountStopCriteriumTest.cs
  21. 1
      src/Numerics.Tests/LinearAlgebraTests/Single/Solvers/StopCriterion/ResidualStopCriteriumTest.cs
  22. 16
      src/Numerics/Compatibility.cs
  23. 17
      src/Numerics/Complex32.cs
  24. 11
      src/Numerics/ComplexExtensions.cs
  25. 6
      src/Numerics/Differentiation/FiniteDifferenceCoefficients.cs
  26. 11
      src/Numerics/Differentiation/NumericalDerivative.cs
  27. 2
      src/Numerics/Differentiation/NumericalHessian.cs
  28. 2
      src/Numerics/Differentiation/NumericalJacobian.cs
  29. 4
      src/Numerics/Distance.cs
  30. 66
      src/Numerics/Distributions/Burr.cs
  31. 35
      src/Numerics/Distributions/InverseGaussian.cs
  32. 19
      src/Numerics/Distributions/Logistic.cs
  33. 7
      src/Numerics/Distributions/Normal.cs
  34. 10
      src/Numerics/Distributions/SkewedGeneralizedError.cs
  35. 10
      src/Numerics/Distributions/TruncatedPareto.cs
  36. 179
      src/Numerics/Integration/GaussKronrodRule.cs
  37. 2
      src/Numerics/Integration/GaussLegendreRule.cs
  38. 37
      src/Numerics/Integration/GaussRule/GaussKronrodPoint.cs
  39. 12
      src/Numerics/Integration/GaussRule/GaussKronrodPointFactory.cs
  40. 4
      src/Numerics/Integration/GaussRule/GaussLegendrePointFactory.cs
  41. 12
      src/Numerics/Integration/GaussRule/GaussPoint.cs
  42. 20
      src/Numerics/Integration/GaussRule/GaussPointPair.cs
  43. 2
      src/Numerics/Interpolate.cs
  44. 20
      src/Numerics/Interpolation/Barycentric.cs
  45. 20
      src/Numerics/Interpolation/BulirschStoerRationalInterpolation.cs
  46. 9
      src/Numerics/Interpolation/CubicSpline.cs
  47. 10
      src/Numerics/Interpolation/LinearSpline.cs
  48. 10
      src/Numerics/Interpolation/LogLinear.cs
  49. 10
      src/Numerics/Interpolation/NevillePolynomialInterpolation.cs
  50. 5
      src/Numerics/Interpolation/QuadraticSpline.cs
  51. 10
      src/Numerics/Interpolation/StepInterpolation.cs
  52. 25
      src/Numerics/Interpolation/TransformedInterpolation.cs
  53. 4
      src/Numerics/LinearAlgebra/Builder.cs
  54. 2
      src/Numerics/LinearAlgebra/Complex/Factorization/DenseGramSchmidt.cs
  55. 2
      src/Numerics/LinearAlgebra/Complex/Matrix.cs
  56. 14
      src/Numerics/LinearAlgebra/Complex/Solvers/ILUTPPreconditioner.cs
  57. 8
      src/Numerics/LinearAlgebra/Complex/Solvers/MILU0Preconditioner.cs
  58. 8
      src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs
  59. 2
      src/Numerics/LinearAlgebra/Complex/Vector.cs
  60. 4
      src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs
  61. 2
      src/Numerics/LinearAlgebra/Complex32/Factorization/DenseGramSchmidt.cs
  62. 14
      src/Numerics/LinearAlgebra/Complex32/Solvers/ILUTPPreconditioner.cs
  63. 8
      src/Numerics/LinearAlgebra/Complex32/Solvers/MILU0Preconditioner.cs
  64. 8
      src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs
  65. 2
      src/Numerics/LinearAlgebra/Double/Factorization/DenseGramSchmidt.cs
  66. 2
      src/Numerics/LinearAlgebra/Double/Matrix.cs
  67. 14
      src/Numerics/LinearAlgebra/Double/Solvers/ILUTPPreconditioner.cs
  68. 8
      src/Numerics/LinearAlgebra/Double/Solvers/MILU0Preconditioner.cs
  69. 8
      src/Numerics/LinearAlgebra/Double/SparseMatrix.cs
  70. 2
      src/Numerics/LinearAlgebra/Double/Vector.cs
  71. 2
      src/Numerics/LinearAlgebra/Factorization/Cholesky.cs
  72. 8
      src/Numerics/LinearAlgebra/Factorization/Evd.cs
  73. 2
      src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs
  74. 2
      src/Numerics/LinearAlgebra/Single/Factorization/DenseGramSchmidt.cs
  75. 6
      src/Numerics/LinearAlgebra/Single/Matrix.cs
  76. 14
      src/Numerics/LinearAlgebra/Single/Solvers/ILUTPPreconditioner.cs
  77. 8
      src/Numerics/LinearAlgebra/Single/Solvers/MILU0Preconditioner.cs
  78. 8
      src/Numerics/LinearAlgebra/Single/SparseMatrix.cs
  79. 8
      src/Numerics/LinearAlgebra/Single/Vector.cs
  80. 3
      src/Numerics/Optimization/BfgsBMinimizer.cs
  81. 1
      src/Numerics/Optimization/BfgsMinimizer.cs
  82. 4
      src/Numerics/Optimization/BfgsMinimizerBase.cs
  83. 4
      src/Numerics/Optimization/BfgsSolver.cs
  84. 6
      src/Numerics/Optimization/Exceptions.cs
  85. 6
      src/Numerics/Optimization/GoldenSectionMinimizer.cs
  86. 36
      src/Numerics/Optimization/LevenbergMarquardtMinimizer.cs
  87. 3
      src/Numerics/Optimization/LimitedMemoryBfgsMinimizer.cs
  88. 2
      src/Numerics/Optimization/LineSearch/LineSearchResult.cs
  89. 4
      src/Numerics/Optimization/MinimizationWithLineSearchResult.cs
  90. 14
      src/Numerics/Optimization/NelderMeadSimplex.cs
  91. 2
      src/Numerics/Optimization/NonlinearMinimizationResult.cs
  92. 33
      src/Numerics/Optimization/NonlinearMinimizerBase.cs
  93. 10
      src/Numerics/Optimization/ObjectiveFunction.cs
  94. 6
      src/Numerics/Optimization/ObjectiveFunctions/ForwardDifferenceGradientObjectiveFunction.cs
  95. 4
      src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunction.cs
  96. 4
      src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunctionBase.cs
  97. 168
      src/Numerics/Optimization/ObjectiveFunctions/NonlinearObjectiveFunction.cs
  98. 4
      src/Numerics/Optimization/ObjectiveFunctions/ObjectiveFunctionBase.cs
  99. 15
      src/Numerics/Optimization/TrustRegion/TrustRegionMinimizerBase.cs
  100. 2
      src/Numerics/Permutation.cs

6
MathNet.Numerics.sln.DotSettings

@ -70,10 +70,12 @@ OTHER DEALINGS IN THE SOFTWARE.
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MKL/@EntryIndexedValue">MKL</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MKL/@EntryIndexedValue">MKL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MSE/@EntryIndexedValue">MSE</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MSE/@EntryIndexedValue">MSE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PDF/@EntryIndexedValue">PDF</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PDF/@EntryIndexedValue">PDF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PMF/@EntryIndexedValue">PMF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=QR/@EntryIndexedValue">QR</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=QR/@EntryIndexedValue">QR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SAD/@EntryIndexedValue">SAD</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SAD/@EntryIndexedValue">SAD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SAS/@EntryIndexedValue">SAS</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SAS/@EntryIndexedValue">SAS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SPSS/@EntryIndexedValue">SPSS</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SPSS/@EntryIndexedValue">SPSS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SQR/@EntryIndexedValue">SQR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SS/@EntryIndexedValue">SS</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SS/@EntryIndexedValue">SS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SSD/@EntryIndexedValue">SSD</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SSD/@EntryIndexedValue">SSD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SVD/@EntryIndexedValue">SVD</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SVD/@EntryIndexedValue">SVD</s:String>
@ -88,8 +90,12 @@ OTHER DEALINGS IN THE SOFTWARE.&#xD;
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Abcissas/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Chebychev/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Chebychev/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Cholesky/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Cholesky/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Cosecant/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Jaccard/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kronrod/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=NONINFRINGEMENT/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=NONINFRINGEMENT/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Numerics/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Numerics/@EntryIndexedValue">True</s:Boolean>

2
src/NativeProviders/Windows/MKL/MKLWrapper.vcxproj

@ -212,4 +212,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project> </Project>

6
src/Numerics.Tests/DistributionTests/Continuous/BurrTests.cs

@ -57,9 +57,9 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous
public void CanCreateBurr(double a, double c, double k) public void CanCreateBurr(double a, double c, double k)
{ {
var n = new Burr(a, c, k); var n = new Burr(a, c, k);
Assert.AreEqual(a, n.a); Assert.AreEqual(a, n.A);
Assert.AreEqual(c, n.c); Assert.AreEqual(c, n.C);
Assert.AreEqual(k, n.k); Assert.AreEqual(k, n.K);
} }
/// <summary> /// <summary>

2
src/Numerics.Tests/DistributionTests/Continuous/InverseGaussianTests.cs

@ -305,7 +305,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous
public void ValidateInverseCumulativeDistribution(double mu, double lambda, double probability, double f) public void ValidateInverseCumulativeDistribution(double mu, double lambda, double probability, double f)
{ {
var n = new InverseGaussian(mu, lambda); var n = new InverseGaussian(mu, lambda);
AssertHelpers.AlmostEqualRelative(f, InverseGaussian.ICDF(mu, lambda, probability), precision); AssertHelpers.AlmostEqualRelative(f, InverseGaussian.InvCDF(mu, lambda, probability), precision);
AssertHelpers.AlmostEqualRelative(f, n.InvCDF(probability), precision); AssertHelpers.AlmostEqualRelative(f, n.InvCDF(probability), precision);
} }

2
src/Numerics.Tests/DistributionTests/Continuous/TruncatedParetoTests.cs

@ -350,7 +350,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous
{ {
var n = new TruncatedPareto(scale, shape, truncation); var n = new TruncatedPareto(scale, shape, truncation);
AssertHelpers.AlmostEqualRelative(expected, n.InvCDF(p), lowPrecision); AssertHelpers.AlmostEqualRelative(expected, n.InvCDF(p), lowPrecision);
AssertHelpers.AlmostEqualRelative(expected, TruncatedPareto.ICDF(scale, shape, truncation, p), lowPrecision); AssertHelpers.AlmostEqualRelative(expected, TruncatedPareto.InvCDF(scale, shape, truncation, p), lowPrecision);
} }
/// <summary> /// <summary>

3
src/Numerics.Tests/DistributionTests/Discrete/CategoricalTests.cs

@ -105,9 +105,8 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete
public void CategoricalCreateFailsWithNullHistogram() public void CategoricalCreateFailsWithNullHistogram()
{ {
Histogram h = null; Histogram h = null;
// ReSharper disable ExpressionIsAlwaysNull // ReSharper disable once ExpressionIsAlwaysNull
Assert.That(() => new Categorical(h), Throws.TypeOf<ArgumentNullException>()); Assert.That(() => new Categorical(h), Throws.TypeOf<ArgumentNullException>());
// ReSharper restore ExpressionIsAlwaysNull
} }
/// <summary> /// <summary>

3
src/Numerics.Tests/DistributionTests/Multivariate/MultinomialTests.cs

@ -107,9 +107,8 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate
public void MultinomialCreateFailsWithNullHistogram() public void MultinomialCreateFailsWithNullHistogram()
{ {
Histogram h = null; Histogram h = null;
// ReSharper disable ExpressionIsAlwaysNull // ReSharper disable once ExpressionIsAlwaysNull
Assert.That(() => new Categorical(h), Throws.TypeOf<ArgumentNullException>()); Assert.That(() => new Categorical(h), Throws.TypeOf<ArgumentNullException>());
// ReSharper restore ExpressionIsAlwaysNull
} }
/// <summary> /// <summary>

3
src/Numerics.Tests/FinancialTests/CompoundReturnTests.cs

@ -43,9 +43,8 @@ namespace MathNet.Numerics.UnitTests.FinancialTests
//arrange //arrange
List<double> inputData = null; List<double> inputData = null;
//act //act
// ReSharper disable ExpressionIsAlwaysNull // ReSharper disable once ExpressionIsAlwaysNull
Assert.Throws<ArgumentNullException>(() => AbsoluteReturnMeasures.CompoundReturn(inputData)); Assert.Throws<ArgumentNullException>(() => AbsoluteReturnMeasures.CompoundReturn(inputData));
// ReSharper restore ExpressionIsAlwaysNull
} }
[Test] [Test]

3
src/Numerics.Tests/FinancialTests/DownsideDeviationTests.cs

@ -108,9 +108,8 @@ namespace MathNet.Numerics.UnitTests.FinancialTests
const double minimumAcceptableReturn = 0.05; const double minimumAcceptableReturn = 0.05;
List<double> inputData = null; List<double> inputData = null;
//act //act
// ReSharper disable ExpressionIsAlwaysNull // ReSharper disable once ExpressionIsAlwaysNull
Assert.Throws<ArgumentNullException>(() => AbsoluteRiskMeasures.DownsideDeviation(inputData, minimumAcceptableReturn)); Assert.Throws<ArgumentNullException>(() => AbsoluteRiskMeasures.DownsideDeviation(inputData, minimumAcceptableReturn));
// ReSharper restore ExpressionIsAlwaysNull
} }
} }

3
src/Numerics.Tests/FinancialTests/GainLossRatioTests.cs

@ -45,9 +45,8 @@ namespace MathNet.Numerics.UnitTests.FinancialTests
//arrange //arrange
List<double> inputData = null; List<double> inputData = null;
//act //act
// ReSharper disable ExpressionIsAlwaysNull // ReSharper disable once ExpressionIsAlwaysNull
Assert.Throws<ArgumentNullException>(() => AbsoluteRiskMeasures.GainLossRatio(inputData)); Assert.Throws<ArgumentNullException>(() => AbsoluteRiskMeasures.GainLossRatio(inputData));
// ReSharper restore ExpressionIsAlwaysNull
} }
[Test] [Test]

3
src/Numerics.Tests/FinancialTests/GainMeanTests.cs

@ -88,9 +88,8 @@ namespace MathNet.Numerics.UnitTests.FinancialTests
//arrange //arrange
double[] inputData = null; double[] inputData = null;
//act //act
// ReSharper disable ExpressionIsAlwaysNull // ReSharper disable once ExpressionIsAlwaysNull
Assert.Throws<ArgumentNullException>(() => AbsoluteReturnMeasures.GainMean(inputData)); Assert.Throws<ArgumentNullException>(() => AbsoluteReturnMeasures.GainMean(inputData));
// ReSharper restore ExpressionIsAlwaysNull
} }
[Test] [Test]

3
src/Numerics.Tests/FinancialTests/GainStandardDeviationTests.cs

@ -113,9 +113,8 @@ namespace MathNet.Numerics.UnitTests.FinancialTests
//arrange //arrange
List<double> inputData = null; List<double> inputData = null;
//act //act
// ReSharper disable ExpressionIsAlwaysNull // ReSharper disable once ExpressionIsAlwaysNull
Assert.Throws<ArgumentNullException>(() => AbsoluteRiskMeasures.GainStandardDeviation(inputData)); Assert.Throws<ArgumentNullException>(() => AbsoluteRiskMeasures.GainStandardDeviation(inputData));
// ReSharper restore ExpressionIsAlwaysNull
} }
} }
} }

3
src/Numerics.Tests/FinancialTests/LossMeanTests.cs

@ -89,9 +89,8 @@ namespace MathNet.Numerics.UnitTests.FinancialTests
//arrange //arrange
List<double> inputData = null; List<double> inputData = null;
//act //act
// ReSharper disable ExpressionIsAlwaysNull // ReSharper disable once ExpressionIsAlwaysNull
Assert.Throws<ArgumentNullException>(() => AbsoluteReturnMeasures.LossMean(inputData)); Assert.Throws<ArgumentNullException>(() => AbsoluteReturnMeasures.LossMean(inputData));
// ReSharper restore ExpressionIsAlwaysNull
} }
[Test] [Test]

3
src/Numerics.Tests/FinancialTests/LossStandardDeviationTests.cs

@ -113,9 +113,8 @@ namespace MathNet.Numerics.UnitTests.FinancialTests
//arrange //arrange
List<double> inputData = null; List<double> inputData = null;
//act //act
// ReSharper disable ExpressionIsAlwaysNull // ReSharper disable once ExpressionIsAlwaysNull
Assert.Throws<ArgumentNullException>(() => AbsoluteRiskMeasures.LossStandardDeviation(inputData)); Assert.Throws<ArgumentNullException>(() => AbsoluteRiskMeasures.LossStandardDeviation(inputData));
// ReSharper restore ExpressionIsAlwaysNull
} }
} }
} }

3
src/Numerics.Tests/FinancialTests/SemiDeviationTests.cs

@ -104,9 +104,8 @@ namespace MathNet.Numerics.UnitTests.FinancialTests
//arrange //arrange
List<double> inputData = null; List<double> inputData = null;
//act //act
// ReSharper disable ExpressionIsAlwaysNull // ReSharper disable once ExpressionIsAlwaysNull
Assert.Throws<ArgumentNullException>(() => AbsoluteRiskMeasures.SemiDeviation(inputData)); Assert.Throws<ArgumentNullException>(() => AbsoluteRiskMeasures.SemiDeviation(inputData));
// ReSharper restore ExpressionIsAlwaysNull
} }
} }
} }

4
src/Numerics.Tests/LinearAlgebraTests/Complex/Solvers/StopCriterion/IterationCountStopCriteriumTest.cs

@ -136,10 +136,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
var clonedCriterion = clone as IterationCountStopCriterion<Complex>; var clonedCriterion = clone as IterationCountStopCriterion<Complex>;
Assert.IsNotNull(clonedCriterion); Assert.IsNotNull(clonedCriterion);
// ReSharper disable PossibleNullReferenceException // ReSharper disable once PossibleNullReferenceException
Assert.AreEqual(criterion.MaximumNumberOfIterations, clonedCriterion.MaximumNumberOfIterations, "Clone failed"); Assert.AreEqual(criterion.MaximumNumberOfIterations, clonedCriterion.MaximumNumberOfIterations, "Clone failed");
// ReSharper restore PossibleNullReferenceException
} }
} }
} }

4
src/Numerics.Tests/LinearAlgebraTests/Complex32/Solvers/StopCriterion/IterationCountStopCriteriumTest.cs

@ -136,10 +136,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
var clonedCriterion = clone as IterationCountStopCriterion<Complex32>; var clonedCriterion = clone as IterationCountStopCriterion<Complex32>;
Assert.IsNotNull(clonedCriterion); Assert.IsNotNull(clonedCriterion);
// ReSharper disable PossibleNullReferenceException // ReSharper disable once PossibleNullReferenceException
Assert.AreEqual(criterion.MaximumNumberOfIterations, clonedCriterion.MaximumNumberOfIterations, "Clone failed"); Assert.AreEqual(criterion.MaximumNumberOfIterations, clonedCriterion.MaximumNumberOfIterations, "Clone failed");
// ReSharper restore PossibleNullReferenceException
} }
} }
} }

4
src/Numerics.Tests/LinearAlgebraTests/Double/Solvers/StopCriterion/IterationCountStopCriteriumTest.cs

@ -134,10 +134,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
var clonedCriterion = clone as IterationCountStopCriterion<double>; var clonedCriterion = clone as IterationCountStopCriterion<double>;
Assert.IsNotNull(clonedCriterion); Assert.IsNotNull(clonedCriterion);
// ReSharper disable PossibleNullReferenceException // ReSharper disable once PossibleNullReferenceException
Assert.AreEqual(criterion.MaximumNumberOfIterations, clonedCriterion.MaximumNumberOfIterations, "Clone failed"); Assert.AreEqual(criterion.MaximumNumberOfIterations, clonedCriterion.MaximumNumberOfIterations, "Clone failed");
// ReSharper restore PossibleNullReferenceException
} }
} }
} }

1
src/Numerics.Tests/LinearAlgebraTests/Double/Solvers/StopCriterion/ResidualStopCriteriumTest.cs

@ -235,7 +235,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
// ReSharper disable PossibleNullReferenceException // ReSharper disable PossibleNullReferenceException
Assert.AreEqual(criterion.Maximum, clonedCriterion.Maximum, "Clone failed"); Assert.AreEqual(criterion.Maximum, clonedCriterion.Maximum, "Clone failed");
Assert.AreEqual(criterion.MinimumIterationsBelowMaximum, clonedCriterion.MinimumIterationsBelowMaximum, "Clone failed"); Assert.AreEqual(criterion.MinimumIterationsBelowMaximum, clonedCriterion.MinimumIterationsBelowMaximum, "Clone failed");
// ReSharper restore PossibleNullReferenceException // ReSharper restore PossibleNullReferenceException
} }
} }

4
src/Numerics.Tests/LinearAlgebraTests/Single/Solvers/StopCriterion/IterationCountStopCriteriumTest.cs

@ -134,10 +134,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
var clonedCriterion = clone as IterationCountStopCriterion<float>; var clonedCriterion = clone as IterationCountStopCriterion<float>;
Assert.IsNotNull(clonedCriterion); Assert.IsNotNull(clonedCriterion);
// ReSharper disable PossibleNullReferenceException // ReSharper disable once PossibleNullReferenceException
Assert.AreEqual(criterion.MaximumNumberOfIterations, clonedCriterion.MaximumNumberOfIterations, "Clone failed"); Assert.AreEqual(criterion.MaximumNumberOfIterations, clonedCriterion.MaximumNumberOfIterations, "Clone failed");
// ReSharper restore PossibleNullReferenceException
} }
} }
} }

1
src/Numerics.Tests/LinearAlgebraTests/Single/Solvers/StopCriterion/ResidualStopCriteriumTest.cs

@ -239,7 +239,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
// ReSharper disable PossibleNullReferenceException // ReSharper disable PossibleNullReferenceException
Assert.AreEqual(criterion.Maximum, clonedCriterion.Maximum, "Clone failed"); Assert.AreEqual(criterion.Maximum, clonedCriterion.Maximum, "Clone failed");
Assert.AreEqual(criterion.MinimumIterationsBelowMaximum, clonedCriterion.MinimumIterationsBelowMaximum, "Clone failed"); Assert.AreEqual(criterion.MinimumIterationsBelowMaximum, clonedCriterion.MinimumIterationsBelowMaximum, "Clone failed");
// ReSharper restore PossibleNullReferenceException // ReSharper restore PossibleNullReferenceException
} }
} }

16
src/Numerics/Compatibility.cs

@ -1,6 +1,6 @@
using System.Globalization; #if NET40
using System.Globalization;
#if NET40
namespace System.Runtime.CompilerServices namespace System.Runtime.CompilerServices
{ {
internal class FormattableStringFactory internal class FormattableStringFactory
@ -16,13 +16,13 @@ namespace System
{ {
internal class FormattableString internal class FormattableString
{ {
private readonly string format; readonly string _format;
private readonly object[] args; readonly object[] _args;
public FormattableString(string format, object[] args) public FormattableString(string format, object[] args)
{ {
this.format = format; _format = format;
this.args = args; _args = args;
} }
public static string Invariant(FormattableString messageFormat) public static string Invariant(FormattableString messageFormat)
@ -32,12 +32,12 @@ namespace System
public string ToString(IFormatProvider formatProvider) public string ToString(IFormatProvider formatProvider)
{ {
return string.Format(formatProvider, format, args); return string.Format(formatProvider, _format, _args);
} }
public override string ToString() public override string ToString()
{ {
return string.Format(format, args); return string.Format(_format, _args);
} }
} }
} }

17
src/Numerics/Complex32.cs

@ -73,13 +73,13 @@ namespace MathNet.Numerics
/// The real component of the complex number. /// The real component of the complex number.
/// </summary> /// </summary>
[DataMember(Order = 1)] [DataMember(Order = 1)]
private readonly float _real; readonly float _real;
/// <summary> /// <summary>
/// The imaginary component of the complex number. /// The imaginary component of the complex number.
/// </summary> /// </summary>
[DataMember(Order = 2)] [DataMember(Order = 2)]
private readonly float _imag; readonly float _imag;
/// <summary> /// <summary>
/// Initializes a new instance of the Complex32 structure with the given real /// Initializes a new instance of the Complex32 structure with the given real
@ -668,7 +668,7 @@ namespace MathNet.Numerics
/// <param name="d">Im second</param> /// <param name="d">Im second</param>
/// <param name="swapped"></param> /// <param name="swapped"></param>
/// <returns></returns> /// <returns></returns>
private static Complex32 InternalDiv(float a, float b, float c, float d, bool swapped) static Complex32 InternalDiv(float a, float b, float c, float d, bool swapped)
{ {
float r = d / c; float r = d / c;
float t = 1 / (c + d * r); float t = 1 / (c + d * r);
@ -927,8 +927,7 @@ namespace MathNet.Numerics
var token = tokens.First; var token = tokens.First;
// parse the left part // parse the left part
bool isLeftPartImaginary; var leftPart = ParsePart(ref token, out var isLeftPartImaginary, formatProvider);
var leftPart = ParsePart(ref token, out isLeftPartImaginary, formatProvider);
if (token == null) if (token == null)
{ {
return isLeftPartImaginary ? new Complex32(0, leftPart) : new Complex32(leftPart, 0); return isLeftPartImaginary ? new Complex32(0, leftPart) : new Complex32(leftPart, 0);
@ -946,16 +945,14 @@ namespace MathNet.Numerics
throw new FormatException(); throw new FormatException();
} }
bool isRightPartImaginary; var rightPart = ParsePart(ref token, out _, formatProvider);
var rightPart = ParsePart(ref token, out isRightPartImaginary, formatProvider);
return new Complex32(leftPart, rightPart); return new Complex32(leftPart, rightPart);
} }
else else
{ {
// format: real + imag // format: real + imag
bool isRightPartImaginary; var rightPart = ParsePart(ref token, out var isRightPartImaginary, formatProvider);
var rightPart = ParsePart(ref token, out isRightPartImaginary, formatProvider);
if (!(isLeftPartImaginary ^ isRightPartImaginary)) if (!(isLeftPartImaginary ^ isRightPartImaginary))
{ {
@ -978,7 +975,7 @@ namespace MathNet.Numerics
/// </param> /// </param>
/// <returns>Resulting part as float.</returns> /// <returns>Resulting part as float.</returns>
/// <exception cref="FormatException"/> /// <exception cref="FormatException"/>
private static float ParsePart(ref LinkedListNode<string> token, out bool imaginary, IFormatProvider format) static float ParsePart(ref LinkedListNode<string> token, out bool imaginary, IFormatProvider format)
{ {
imaginary = false; imaginary = false;
if (token == null) if (token == null)

11
src/Numerics/ComplexExtensions.cs

@ -506,8 +506,7 @@ namespace MathNet.Numerics
var token = tokens.First; var token = tokens.First;
// parse the left part // parse the left part
bool isLeftPartImaginary; var leftPart = ParsePart(ref token, out var isLeftPartImaginary, formatProvider);
var leftPart = ParsePart(ref token, out isLeftPartImaginary, formatProvider);
if (token == null) if (token == null)
{ {
return isLeftPartImaginary ? new Complex(0, leftPart) : new Complex(leftPart, 0); return isLeftPartImaginary ? new Complex(0, leftPart) : new Complex(leftPart, 0);
@ -525,16 +524,14 @@ namespace MathNet.Numerics
throw new FormatException(); throw new FormatException();
} }
bool isRightPartImaginary; var rightPart = ParsePart(ref token, out _, formatProvider);
var rightPart = ParsePart(ref token, out isRightPartImaginary, formatProvider);
return new Complex(leftPart, rightPart); return new Complex(leftPart, rightPart);
} }
else else
{ {
// format: real + imag // format: real + imag
bool isRightPartImaginary; var rightPart = ParsePart(ref token, out var isRightPartImaginary, formatProvider);
var rightPart = ParsePart(ref token, out isRightPartImaginary, formatProvider);
if (!(isLeftPartImaginary ^ isRightPartImaginary)) if (!(isLeftPartImaginary ^ isRightPartImaginary))
{ {
@ -557,7 +554,7 @@ namespace MathNet.Numerics
/// </param> /// </param>
/// <returns>Resulting part as double.</returns> /// <returns>Resulting part as double.</returns>
/// <exception cref="FormatException"/> /// <exception cref="FormatException"/>
private static double ParsePart(ref LinkedListNode<string> token, out bool imaginary, IFormatProvider format) static double ParsePart(ref LinkedListNode<string> token, out bool imaginary, IFormatProvider format)
{ {
imaginary = false; imaginary = false;
if (token == null) if (token == null)

6
src/Numerics/Differentiation/FiniteDifferenceCoefficients.cs

@ -57,8 +57,8 @@ namespace MathNet.Numerics.Differentiation
} }
} }
private double[][,] _coefficients; double[][,] _coefficients;
private int _points; int _points;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="FiniteDifferenceCoefficients"/> class. /// Initializes a new instance of the <see cref="FiniteDifferenceCoefficients"/> class.
@ -104,7 +104,7 @@ namespace MathNet.Numerics.Differentiation
return _coefficients[center]; return _coefficients[center];
} }
private void CalculateCoefficients(int points) void CalculateCoefficients(int points)
{ {
var c = new double[points][,]; var c = new double[points][,];

11
src/Numerics/Differentiation/NumericalDerivative.cs

@ -433,16 +433,7 @@ namespace MathNet.Numerics.Differentiation
Evaluations = 0; Evaluations = 0;
} }
private double[] CalculateStepSize(int points, double[] x, double order) double CalculateStepSize(int points, double x, double order)
{
var h = new double[x.Length];
for (int i = 1; i < h.Length; i++)
h[i] = CalculateStepSize(points, x[i], order);
return h;
}
private double CalculateStepSize(int points, double x, double order)
{ {
// Step size relative to function input parameter // Step size relative to function input parameter
if (StepType == StepType.RelativeX) if (StepType == StepType.RelativeX)

2
src/Numerics/Differentiation/NumericalHessian.cs

@ -42,7 +42,7 @@ namespace MathNet.Numerics.Differentiation
/// </summary> /// </summary>
public int FunctionEvaluations => _df.Evaluations; public int FunctionEvaluations => _df.Evaluations;
private readonly NumericalDerivative _df; readonly NumericalDerivative _df;
/// <summary> /// <summary>
/// Creates a numerical Hessian object with a three point central difference method. /// Creates a numerical Hessian object with a three point central difference method.

2
src/Numerics/Differentiation/NumericalJacobian.cs

@ -42,7 +42,7 @@ namespace MathNet.Numerics.Differentiation
/// </summary> /// </summary>
public int FunctionEvaluations => _df.Evaluations; public int FunctionEvaluations => _df.Evaluations;
private readonly NumericalDerivative _df; readonly NumericalDerivative _df;
/// <summary> /// <summary>
/// Creates a numerical Jacobian object with a three point central difference method. /// Creates a numerical Jacobian object with a three point central difference method.

4
src/Numerics/Distance.cs

@ -517,7 +517,7 @@ namespace MathNet.Numerics
} }
} }
return 1.0 - ((double)intersection / (double)union); return 1.0 - ((double)intersection / union);
} }
/// <summary> /// <summary>
@ -563,7 +563,7 @@ namespace MathNet.Numerics
} }
} }
return 1.0 - ((float)intersection / (float)union); return 1.0 - ((float)intersection / union);
} }
} }
} }

66
src/Numerics/Distributions/Burr.cs

@ -40,17 +40,17 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Gets the scale (a) of the distribution. Range: a > 0. /// Gets the scale (a) of the distribution. Range: a > 0.
/// </summary> /// </summary>
public double a { get; } public double A { get; }
/// <summary> /// <summary>
/// Gets the first shape parameter (c) of the distribution. Range: c > 0. /// Gets the first shape parameter (c) of the distribution. Range: c > 0.
/// </summary> /// </summary>
public double c { get; } public double C { get; }
/// <summary> /// <summary>
/// Gets the second shape parameter (k) of the distribution. Range: k > 0. /// Gets the second shape parameter (k) of the distribution. Range: k > 0.
/// </summary> /// </summary>
public double k { get; } public double K { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the Burr Type XII class. /// Initializes a new instance of the Burr Type XII class.
@ -66,9 +66,9 @@ namespace MathNet.Numerics.Distributions
throw new ArgumentException("Invalid parametrization for the distribution."); throw new ArgumentException("Invalid parametrization for the distribution.");
} }
_random = randomSource ?? SystemRandomSource.Default; _random = randomSource ?? SystemRandomSource.Default;
this.a = a; A = a;
this.c = c; C = c;
this.k = k; K = k;
} }
/// <summary> /// <summary>
@ -77,7 +77,7 @@ namespace MathNet.Numerics.Distributions
/// <returns>a string representation of the distribution.</returns> /// <returns>a string representation of the distribution.</returns>
public override string ToString() public override string ToString()
{ {
return $"Burr(a = {a}, c = {c}, k = {k})"; return $"Burr(a = {A}, c = {C}, k = {K})";
} }
/// <summary> /// <summary>
@ -104,14 +104,14 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Gets the mean of the Burr distribution. /// Gets the mean of the Burr distribution.
/// </summary> /// </summary>
public double Mean => (1 / SpecialFunctions.Gamma(k)) * a * SpecialFunctions.Gamma(1 + 1 / c) * SpecialFunctions.Gamma(k - 1 / c); public double Mean => (1 / SpecialFunctions.Gamma(K)) * A * SpecialFunctions.Gamma(1 + 1 / C) * SpecialFunctions.Gamma(K - 1 / C);
/// <summary> /// <summary>
/// Gets the variance of the Burr distribution. /// Gets the variance of the Burr distribution.
/// </summary> /// </summary>
public double Variance => public double Variance =>
(1 / SpecialFunctions.Gamma(k)) * Math.Pow(a, 2) * SpecialFunctions.Gamma(1 + 2 / c) * SpecialFunctions.Gamma(k - 2 / c) (1 / SpecialFunctions.Gamma(K)) * Math.Pow(A, 2) * SpecialFunctions.Gamma(1 + 2 / C) * SpecialFunctions.Gamma(K - 2 / C)
- Math.Pow((1 / SpecialFunctions.Gamma(k)) * a * SpecialFunctions.Gamma(1 + 1 / c) * SpecialFunctions.Gamma(k - 1 / c), 2); - Math.Pow((1 / SpecialFunctions.Gamma(K)) * A * SpecialFunctions.Gamma(1 + 1 / C) * SpecialFunctions.Gamma(K - 1 / C), 2);
/// <summary> /// <summary>
/// Gets the standard deviation of the Burr distribution. /// Gets the standard deviation of the Burr distribution.
@ -121,7 +121,7 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Gets the mode of the Burr distribution. /// Gets the mode of the Burr distribution.
/// </summary> /// </summary>
public double Mode => a * Math.Pow((c - 1) / (c * k + 1), 1 / c); public double Mode => A * Math.Pow((C - 1) / (C * K + 1), 1 / C);
/// <summary> /// <summary>
/// Gets the minimum of the Burr distribution. /// Gets the minimum of the Burr distribution.
@ -155,7 +155,7 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Gets the median of the Burr distribution. /// Gets the median of the Burr distribution.
/// </summary> /// </summary>
public double Median => a * Math.Pow(Math.Pow(2, 1 / k) - 1, 1 / c); public double Median => A * Math.Pow(Math.Pow(2, 1 / K) - 1, 1 / C);
/// <summary> /// <summary>
/// Generates a sample from the Burr distribution. /// Generates a sample from the Burr distribution.
@ -163,7 +163,7 @@ namespace MathNet.Numerics.Distributions
/// <returns>a sample from the distribution.</returns> /// <returns>a sample from the distribution.</returns>
public double Sample() public double Sample()
{ {
return SampleUnchecked(_random, a, c, k); return SampleUnchecked(_random, A, C, K);
} }
/// <summary> /// <summary>
@ -172,7 +172,7 @@ namespace MathNet.Numerics.Distributions
/// <param name="values">The array to fill with the samples.</param> /// <param name="values">The array to fill with the samples.</param>
public void Samples(double[] values) public void Samples(double[] values)
{ {
SamplesUnchecked(_random, values, a, c, k); SamplesUnchecked(_random, values, A, C, K);
} }
/// <summary> /// <summary>
@ -181,7 +181,7 @@ namespace MathNet.Numerics.Distributions
/// <returns>a sequence of samples from the distribution.</returns> /// <returns>a sequence of samples from the distribution.</returns>
public IEnumerable<double> Samples() public IEnumerable<double> Samples()
{ {
return SamplesUnchecked(_random, a, c, k); return SamplesUnchecked(_random, A, C, K);
} }
/// <summary> /// <summary>
@ -235,31 +235,31 @@ namespace MathNet.Numerics.Distributions
return SamplesUnchecked(rnd, a, c, k); return SamplesUnchecked(rnd, a, c, k);
} }
internal static double SampleUnchecked(System.Random rnd, double a, double c, double k) static double SampleUnchecked(System.Random rnd, double a, double c, double k)
{ {
var k_inv = 1 / k; var kInv = 1 / k;
var c_inv = 1 / c; var cInv = 1 / c;
double u = rnd.NextDouble(); double u = rnd.NextDouble();
return a * Math.Pow(Math.Pow(1 - u, -k_inv) - 1, c_inv); return a * Math.Pow(Math.Pow(1 - u, -kInv) - 1, cInv);
} }
internal static void SamplesUnchecked(System.Random rnd, double[] values, double a, double c, double k) static void SamplesUnchecked(System.Random rnd, double[] values, double a, double c, double k)
{ {
if (values.Length == 0) if (values.Length == 0)
{ {
return; return;
} }
var k_inv = 1 / k; var kInv = 1 / k;
var c_inv = 1 / c; var cInv = 1 / c;
double[] u = rnd.NextDoubles(values.Length); double[] u = rnd.NextDoubles(values.Length);
for (var j = 0; j < values.Length; ++j) for (var j = 0; j < values.Length; ++j)
{ {
values[j] = a * Math.Pow(Math.Pow(1 - u[j], -k_inv) - 1, c_inv); values[j] = a * Math.Pow(Math.Pow(1 - u[j], -kInv) - 1, cInv);
} }
} }
internal static IEnumerable<double> SamplesUnchecked(System.Random rnd, double a, double c, double k) static IEnumerable<double> SamplesUnchecked(System.Random rnd, double a, double c, double k)
{ {
while (true) while (true)
{ {
@ -274,12 +274,12 @@ namespace MathNet.Numerics.Distributions
/// <returns>the n-th moment of the distribution.</returns> /// <returns>the n-th moment of the distribution.</returns>
public double GetMoment(double n) public double GetMoment(double n)
{ {
if (n > k * c) if (n > K * C)
{ {
throw new ArgumentException("The chosen parameter set is invalid (probably some value is out of range)."); throw new ArgumentException("The chosen parameter set is invalid (probably some value is out of range).");
} }
var lambda_n = (n / c) * SpecialFunctions.Gamma(n / c) * SpecialFunctions.Gamma(k - n / c); var lambdaN = (n / C) * SpecialFunctions.Gamma(n / C) * SpecialFunctions.Gamma(K - n / C);
return Math.Pow(a, n) * lambda_n / SpecialFunctions.Gamma(k); return Math.Pow(A, n) * lambdaN / SpecialFunctions.Gamma(K);
} }
/// <summary> /// <summary>
@ -290,7 +290,7 @@ namespace MathNet.Numerics.Distributions
/// <seealso cref="PDF"/> /// <seealso cref="PDF"/>
public double Density(double x) public double Density(double x)
{ {
return DensityImpl(a, c, k, x); return DensityImpl(A, C, K, x);
} }
/// <summary> /// <summary>
@ -301,7 +301,7 @@ namespace MathNet.Numerics.Distributions
/// <seealso cref="PDFLn"/> /// <seealso cref="PDFLn"/>
public double DensityLn(double x) public double DensityLn(double x)
{ {
return DensityLnImpl(a, c, k, x); return DensityLnImpl(A, C, K, x);
} }
/// <summary> /// <summary>
@ -312,7 +312,7 @@ namespace MathNet.Numerics.Distributions
/// <seealso cref="CDF"/> /// <seealso cref="CDF"/>
public double CumulativeDistribution(double x) public double CumulativeDistribution(double x)
{ {
return CumulativeDistributionImpl(a, c, k, x); return CumulativeDistributionImpl(A, C, K, x);
} }
/// <summary> /// <summary>
@ -369,19 +369,19 @@ namespace MathNet.Numerics.Distributions
return CumulativeDistributionImpl(a, c, k, x); return CumulativeDistributionImpl(a, c, k, x);
} }
internal static double DensityImpl(double a, double c, double k, double x) static double DensityImpl(double a, double c, double k, double x)
{ {
var numerator = (k * c / a) * Math.Pow(x / a, c - 1); var numerator = (k * c / a) * Math.Pow(x / a, c - 1);
var denominator = Math.Pow(1 + Math.Pow(x / a, c), k + 1); var denominator = Math.Pow(1 + Math.Pow(x / a, c), k + 1);
return numerator / denominator; return numerator / denominator;
} }
internal static double DensityLnImpl(double a, double c, double k, double x) static double DensityLnImpl(double a, double c, double k, double x)
{ {
return Math.Log(DensityImpl(a, c, k, x)); return Math.Log(DensityImpl(a, c, k, x));
} }
internal static double CumulativeDistributionImpl(double a, double c, double k, double x) static double CumulativeDistributionImpl(double a, double c, double k, double x)
{ {
var denominator = Math.Pow(1 + Math.Pow(x / a, c), k); var denominator = Math.Pow(1 + Math.Pow(x / a, c), k);
return 1 - 1 / denominator; return 1 - 1 / denominator;

35
src/Numerics/Distributions/InverseGaussian.cs

@ -221,21 +221,21 @@ namespace MathNet.Numerics.Distributions
return SamplesUnchecked(rnd, mu, lambda); return SamplesUnchecked(rnd, mu, lambda);
} }
internal static double SampleUnchecked(System.Random rnd, double mu, double lambda) static double SampleUnchecked(System.Random rnd, double mu, double lambda)
{ {
double v = MathNet.Numerics.Distributions.Normal.Sample(rnd, 0, 1); double v = Normal.Sample(rnd, 0, 1);
double test = rnd.NextDouble(); double test = rnd.NextDouble();
return InverseGaussianSampleImpl(mu, lambda, v, test); return InverseGaussianSampleImpl(mu, lambda, v, test);
} }
internal static void SamplesUnchecked(System.Random rnd, double[] values, double mu, double lambda) static void SamplesUnchecked(System.Random rnd, double[] values, double mu, double lambda)
{ {
if (values.Length == 0) if (values.Length == 0)
{ {
return; return;
} }
double[] v = new double[values.Length]; double[] v = new double[values.Length];
MathNet.Numerics.Distributions.Normal.Samples(rnd, v, 0, 1); Normal.Samples(rnd, v, 0, 1);
double[] test = rnd.NextDoubles(values.Length); double[] test = rnd.NextDoubles(values.Length);
for (var j = 0; j < values.Length; ++j) for (var j = 0; j < values.Length; ++j)
{ {
@ -243,7 +243,7 @@ namespace MathNet.Numerics.Distributions
} }
} }
internal static IEnumerable<double> SamplesUnchecked(System.Random rnd, double mu, double lambda) static IEnumerable<double> SamplesUnchecked(System.Random rnd, double mu, double lambda)
{ {
while (true) while (true)
{ {
@ -251,7 +251,7 @@ namespace MathNet.Numerics.Distributions
} }
} }
internal static double InverseGaussianSampleImpl(double mu, double lambda, double normalSample, double uniformSample) static double InverseGaussianSampleImpl(double mu, double lambda, double normalSample, double uniformSample)
{ {
double y = normalSample * normalSample; double y = normalSample * normalSample;
double x = mu + (mu * mu * y) / (2 * lambda) - (mu / (2 * lambda)) * Math.Sqrt(4 * mu * lambda * y + mu * mu * y * y); double x = mu + (mu * mu * y) / (2 * lambda) - (mu / (2 * lambda)) * Math.Sqrt(4 * mu * lambda * y + mu * mu * y * y);
@ -301,11 +301,10 @@ namespace MathNet.Numerics.Distributions
/// <returns>the inverse cumulative distribution at location <paramref name="p"/>.</returns> /// <returns>the inverse cumulative distribution at location <paramref name="p"/>.</returns>
public double InvCDF(double p) public double InvCDF(double p)
{ {
Func<double, double> equationToSolve = (x) => CumulativeDistribution(x) - p; double EquationToSolve(double x) => CumulativeDistribution(x) - p;
if (RootFinding.NewtonRaphson.TryFindRoot(equationToSolve, Density, Mode, 0, double.PositiveInfinity, 1e-8, 100, out double quantile)) if (!RootFinding.NewtonRaphson.TryFindRoot(EquationToSolve, Density, Mode, 0, double.PositiveInfinity, 1e-8, 100, out double quantile))
return quantile;
else
throw new NonConvergenceException("Numerical estimation of the statistic has failed. The used solver did not succeed in finding a root."); throw new NonConvergenceException("Numerical estimation of the statistic has failed. The used solver did not succeed in finding a root.");
return quantile;
} }
/// <summary> /// <summary>
@ -367,7 +366,7 @@ namespace MathNet.Numerics.Distributions
/// <param name="p">The location at which to compute the inverse cumulative distribution function.</param> /// <param name="p">The location at which to compute the inverse cumulative distribution function.</param>
/// <returns>the inverse cumulative distribution at location <paramref name="p"/>.</returns> /// <returns>the inverse cumulative distribution at location <paramref name="p"/>.</returns>
/// <seealso cref="CumulativeDistribution"/> /// <seealso cref="CumulativeDistribution"/>
public static double ICDF(double mu, double lambda, double p) public static double InvCDF(double mu, double lambda, double p)
{ {
if (!IsValidParameterSet(mu, lambda)) if (!IsValidParameterSet(mu, lambda))
{ {
@ -385,23 +384,23 @@ namespace MathNet.Numerics.Distributions
/// <returns>An Inverse Gaussian distribution.</returns> /// <returns>An Inverse Gaussian distribution.</returns>
public static InverseGaussian Estimate(IEnumerable<double> samples, System.Random randomSource = null) public static InverseGaussian Estimate(IEnumerable<double> samples, System.Random randomSource = null)
{ {
var sampleVec = samples.ToArray(); var samplesArray = samples.ToArray();
var muHat = sampleVec.Mean(); var muHat = samplesArray.Mean();
var lambdahat = 1 / (1 / samples.HarmonicMean() - 1 / muHat); var lambdaHat = 1 / (1 / samplesArray.HarmonicMean() - 1 / muHat);
return new InverseGaussian(muHat, lambdahat, randomSource); return new InverseGaussian(muHat, lambdaHat, randomSource);
} }
internal static double DensityImpl(double mu, double lambda, double x) static double DensityImpl(double mu, double lambda, double x)
{ {
return Math.Sqrt(lambda / (2 * Math.PI * Math.Pow(x, 3))) * Math.Exp(-((lambda * Math.Pow(x - mu, 2)) / (2 * mu * mu * x))); return Math.Sqrt(lambda / (2 * Math.PI * Math.Pow(x, 3))) * Math.Exp(-((lambda * Math.Pow(x - mu, 2)) / (2 * mu * mu * x)));
} }
internal static double DensityLnImpl(double mu, double lambda, double x) static double DensityLnImpl(double mu, double lambda, double x)
{ {
return Math.Log(Math.Sqrt(lambda / (2 * Math.PI * Math.Pow(x, 3)))) - ((lambda * Math.Pow(x - mu, 2)) / (2 * mu * mu * x)); return Math.Log(Math.Sqrt(lambda / (2 * Math.PI * Math.Pow(x, 3)))) - ((lambda * Math.Pow(x - mu, 2)) / (2 * mu * mu * x));
} }
internal static double CumulativeDistributionImpl(double mu, double lambda, double x) static double CumulativeDistributionImpl(double mu, double lambda, double x)
{ {
return Normal.CDF(0, 1, Math.Sqrt(lambda / x) * (x / mu - 1)) + Math.Exp(2 * lambda / mu) * Normal.CDF(0, 1, -Math.Sqrt(lambda / x) * (x / mu + 1)); return Normal.CDF(0, 1, Math.Sqrt(lambda / x) * (x / mu - 1)) + Math.Exp(2 * lambda / mu) * Normal.CDF(0, 1, -Math.Sqrt(lambda / x) * (x / mu + 1));
} }

19
src/Numerics/Distributions/Logistic.cs

@ -30,7 +30,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using MathNet.Numerics.Random; using MathNet.Numerics.Random;
using MathNet.Numerics.Statistics;
namespace MathNet.Numerics.Distributions namespace MathNet.Numerics.Distributions
{ {
@ -48,7 +47,7 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Initializes a new instance of the Logistic class. This is a logistic distribution with mean 0.0 /// Initializes a new instance of the Logistic class. This is a logistic distribution with mean 0.0
/// and scale 1.0. The distribution will be initialized with the default <seealso cref="System.Random"/> /// and scale 1.0. The distribution will be initialized with the default <seealso cref="System.Random"/>
/// random number generator. /// random number generator.
/// </summary> /// </summary>
public Logistic() public Logistic()
@ -58,7 +57,7 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Initializes a new instance of the Logistic class. This is a logistic distribution with mean 0.0 /// Initializes a new instance of the Logistic class. This is a logistic distribution with mean 0.0
/// and scale 1.0. The distribution will be initialized with the default <seealso cref="System.Random"/> /// and scale 1.0. The distribution will be initialized with the default <seealso cref="System.Random"/>
/// random number generator. /// random number generator.
/// </summary> /// </summary>
/// <param name="randomSource">The random number generator which is used to draw random samples.</param> /// <param name="randomSource">The random number generator which is used to draw random samples.</param>
@ -68,7 +67,7 @@ namespace MathNet.Numerics.Distributions
} }
/// <summary> /// <summary>
/// Initializes a new instance of the Logistic class with a particular mean and scale parameter. The /// Initializes a new instance of the Logistic class with a particular mean and scale parameter. The
/// distribution will be initialized with the default <seealso cref="System.Random"/> random number generator. /// distribution will be initialized with the default <seealso cref="System.Random"/> random number generator.
/// </summary> /// </summary>
/// <param name="mean">The mean (μ) of the logistic distribution.</param> /// <param name="mean">The mean (μ) of the logistic distribution.</param>
@ -307,12 +306,12 @@ namespace MathNet.Numerics.Distributions
return SamplesUnchecked(_random, _mean, _scale); return SamplesUnchecked(_random, _mean, _scale);
} }
internal static double SampleUnchecked(System.Random rnd, double mean, double scale) static double SampleUnchecked(System.Random rnd, double mean, double scale)
{ {
return InvCDF(mean, scale, rnd.NextDouble()); return InvCDF(mean, scale, rnd.NextDouble());
} }
internal static IEnumerable<double> SamplesUnchecked(System.Random rnd, double mean, double scale) static IEnumerable<double> SamplesUnchecked(System.Random rnd, double mean, double scale)
{ {
while (true) while (true)
{ {
@ -320,13 +319,13 @@ namespace MathNet.Numerics.Distributions
} }
} }
internal static void SamplesUnchecked(System.Random rnd, double[] values, double mean, double scale) static void SamplesUnchecked(System.Random rnd, double[] values, double mean, double scale)
{ {
if (values.Length == 0) if (values.Length == 0)
{ {
return; return;
} }
for (int i = 0; i < values.Length; i++) for (int i = 0; i < values.Length; i++)
{ {
values[i] = SampleUnchecked(rnd, mean, scale); values[i] = SampleUnchecked(rnd, mean, scale);
@ -348,7 +347,7 @@ namespace MathNet.Numerics.Distributions
throw new ArgumentException("Invalid parametrization for the distribution."); throw new ArgumentException("Invalid parametrization for the distribution.");
} }
var z = (x - mean)/scale; var z = (x - mean)/scale;
return Math.Exp(-z) / (scale * Math.Pow(1.0 + Math.Exp(-z), 2)); return Math.Exp(-z) / (scale * Math.Pow(1.0 + Math.Exp(-z), 2));
} }
@ -367,7 +366,7 @@ namespace MathNet.Numerics.Distributions
throw new ArgumentException("Invalid parametrization for the distribution."); throw new ArgumentException("Invalid parametrization for the distribution.");
} }
var z = (x - mean)/scale; var z = (x - mean)/scale;
return -z - Math.Log(scale) - (2 * Math.Log(1+Math.Exp(-z))); return -z - Math.Log(scale) - (2 * Math.Log(1+Math.Exp(-z)));
} }

7
src/Numerics/Distributions/Normal.cs

@ -306,8 +306,8 @@ namespace MathNet.Numerics.Distributions
internal static double SampleUnchecked(System.Random rnd, double mean, double stddev) internal static double SampleUnchecked(System.Random rnd, double mean, double stddev)
{ {
double x, y; double x;
while (!PolarTransform(rnd.NextDouble(), rnd.NextDouble(), out x, out y)) while (!PolarTransform(rnd.NextDouble(), rnd.NextDouble(), out x, out _))
{ {
} }
@ -318,8 +318,7 @@ namespace MathNet.Numerics.Distributions
{ {
while (true) while (true)
{ {
double x, y; if (!PolarTransform(rnd.NextDouble(), rnd.NextDouble(), out var x, out var y))
if (!PolarTransform(rnd.NextDouble(), rnd.NextDouble(), out x, out y))
{ {
continue; continue;
} }

10
src/Numerics/Distributions/SkewedGeneralizedError.cs

@ -35,7 +35,7 @@ namespace MathNet.Numerics.Distributions
{ {
/// <summary> /// <summary>
/// Continuous Univariate Skewed Generalized Error Distribution (SGED). /// Continuous Univariate Skewed Generalized Error Distribution (SGED).
/// Implements the univariate SSkewed Generalized Error Distribution. For details about this /// Implements the univariate Skewed Generalized Error Distribution. For details about this
/// distribution, see /// distribution, see
/// <a href="https://en.wikipedia.org/wiki/Generalized_normal_distribution"> /// <a href="https://en.wikipedia.org/wiki/Generalized_normal_distribution">
/// Wikipedia - Generalized Error Distribution</a>. /// Wikipedia - Generalized Error Distribution</a>.
@ -129,22 +129,22 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Gets the location (μ) of the Skewed Generalized t-distribution. /// Gets the location (μ) of the Skewed Generalized t-distribution.
/// </summary> /// </summary>
public double Location { get; private set; } public double Location { get; }
/// <summary> /// <summary>
/// Gets the scale (σ) of the Skewed Generalized t-distribution. Range: σ > 0. /// Gets the scale (σ) of the Skewed Generalized t-distribution. Range: σ > 0.
/// </summary> /// </summary>
public double Scale { get; private set; } public double Scale { get; }
/// <summary> /// <summary>
/// Gets the skew (λ) of the Skewed Generalized t-distribution. Range: 1 > λ > -1. /// Gets the skew (λ) of the Skewed Generalized t-distribution. Range: 1 > λ > -1.
/// </summary> /// </summary>
public double Skew { get; private set; } public double Skew { get; }
/// <summary> /// <summary>
/// Gets the parameter that controls the kurtosis of the distribution. Range: p > 0. /// Gets the parameter that controls the kurtosis of the distribution. Range: p > 0.
/// </summary> /// </summary>
public double P { get; private set; } public double P { get; }
// No skew implies Median=Mode=Mean // No skew implies Median=Mode=Mean
public double Mode => public double Mode =>

10
src/Numerics/Distributions/TruncatedPareto.cs

@ -333,7 +333,7 @@ namespace MathNet.Numerics.Distributions
/// <param name="p">The location at which to compute the inverse cumulative distribution function.</param> /// <param name="p">The location at which to compute the inverse cumulative distribution function.</param>
/// <returns>the inverse cumulative distribution at location <paramref name="p"/>.</returns> /// <returns>the inverse cumulative distribution at location <paramref name="p"/>.</returns>
/// <seealso cref="CumulativeDistribution"/> /// <seealso cref="CumulativeDistribution"/>
public static double ICDF(double scale, double shape, double truncation, double p) public static double InvCDF(double scale, double shape, double truncation, double p)
{ {
if (!IsValidParameterSet(scale, shape, truncation)) if (!IsValidParameterSet(scale, shape, truncation))
{ {
@ -396,7 +396,7 @@ namespace MathNet.Numerics.Distributions
return CumulativeDistributionImpl(scale, shape, truncation, x); return CumulativeDistributionImpl(scale, shape, truncation, x);
} }
internal static double DensityImpl(double scale, double shape, double truncation, double x) static double DensityImpl(double scale, double shape, double truncation, double x)
{ {
if (x < scale || x > truncation) if (x < scale || x > truncation)
return 0; return 0;
@ -404,12 +404,12 @@ namespace MathNet.Numerics.Distributions
return (shape * Math.Pow(scale, shape) * Math.Pow(x, -shape - 1)) / (1 - Math.Pow(scale / truncation, shape)); return (shape * Math.Pow(scale, shape) * Math.Pow(x, -shape - 1)) / (1 - Math.Pow(scale / truncation, shape));
} }
internal static double DensityLnImpl(double scale, double shape, double truncation, double x) static double DensityLnImpl(double scale, double shape, double truncation, double x)
{ {
return Math.Log(DensityImpl(scale, shape, truncation, x)); return Math.Log(DensityImpl(scale, shape, truncation, x));
} }
internal static double CumulativeDistributionImpl(double scale, double shape, double truncation, double x) static double CumulativeDistributionImpl(double scale, double shape, double truncation, double x)
{ {
if (x <= scale) if (x <= scale)
return 0; return 0;
@ -419,7 +419,7 @@ namespace MathNet.Numerics.Distributions
return (1 - Math.Pow(scale, shape) * Math.Pow(x, -shape)) / (1 - Math.Pow(scale / truncation, shape)); return (1 - Math.Pow(scale, shape) * Math.Pow(x, -shape)) / (1 - Math.Pow(scale / truncation, shape));
} }
internal static double InvCDFUncheckedImpl(double scale, double shape, double truncation, double p) static double InvCDFUncheckedImpl(double scale, double shape, double truncation, double p)
{ {
var numerator = p * Math.Pow(truncation, shape) - p * Math.Pow(scale, shape) - Math.Pow(truncation, shape); var numerator = p * Math.Pow(truncation, shape) - p * Math.Pow(scale, shape) - Math.Pow(truncation, shape);
var denominator = Math.Pow(truncation, shape) * Math.Pow(scale, shape); var denominator = Math.Pow(truncation, shape) * Math.Pow(scale, shape);

179
src/Numerics/Integration/GaussKronrodRule.cs

@ -43,31 +43,31 @@ namespace MathNet.Numerics.Integration
{ {
public class GaussKronrodRule public class GaussKronrodRule
{ {
private readonly GaussPointPair gaussKronrodPoint; readonly GaussPointPair _gaussKronrodPoint;
/// <summary> /// <summary>
/// Getter for the order. /// Getter for the order.
/// </summary> /// </summary>
public int Order => gaussKronrodPoint.Order; public int Order => _gaussKronrodPoint.Order;
/// <summary> /// <summary>
/// Getter that returns a clone of the array containing the Kronrod abscissas. /// Getter that returns a clone of the array containing the Kronrod abscissas.
/// </summary> /// </summary>
public double[] KronrodAbscissas => gaussKronrodPoint.Abscissas.Clone() as double[]; public double[] KronrodAbscissas => _gaussKronrodPoint.Abscissas.Clone() as double[];
/// <summary> /// <summary>
/// Getter that returns a clone of the array containing the Kronrod weights. /// Getter that returns a clone of the array containing the Kronrod weights.
/// </summary> /// </summary>
public double[] KronrodWeights => gaussKronrodPoint.Weights.Clone() as double[]; public double[] KronrodWeights => _gaussKronrodPoint.Weights.Clone() as double[];
/// <summary> /// <summary>
/// Getter that returns a clone of the array containing the Gauss weights. /// Getter that returns a clone of the array containing the Gauss weights.
/// </summary> /// </summary>
public double[] GaussWeights => gaussKronrodPoint.SecondWeights.Clone() as double[]; public double[] GaussWeights => _gaussKronrodPoint.SecondWeights.Clone() as double[];
public GaussKronrodRule(int order) public GaussKronrodRule(int order)
{ {
gaussKronrodPoint = GaussKronrodPointFactory.GetGaussPoint(order); _gaussKronrodPoint = GaussKronrodPointFactory.GetGaussPoint(order);
} }
/// <summary> /// <summary>
@ -106,10 +106,7 @@ namespace MathNet.Numerics.Integration
// g'(t) = (1 + t^2) / (1 - t^2)^2 // g'(t) = (1 + t^2) / (1 - t^2)^2
if ((intervalBegin < double.MinValue) && (intervalEnd > double.MaxValue)) if ((intervalBegin < double.MinValue) && (intervalEnd > double.MaxValue))
{ {
Func<double, double> u = (t) => Func<double, double> u = (t) => f(t / (1 - t * t)) * (1 + t * t) / ((1 - t * t) * (1 - t * t));
{
return f(t / (1 - t * t)) * (1 + t * t) / ((1 - t * t) * (1 - t * t));
};
return recursive_adaptive_integrate(u, -1, 1, maximumDepth, targetRelativeError, 0, out error, out L1Norm, gaussKronrodPoint); return recursive_adaptive_integrate(u, -1, 1, maximumDepth, targetRelativeError, 0, out error, out L1Norm, gaussKronrodPoint);
} }
// [a, oo) => [0, 1] // [a, oo) => [0, 1]
@ -120,10 +117,7 @@ namespace MathNet.Numerics.Integration
// g'(s) = 1 / (1 - s)^2 // g'(s) = 1 / (1 - s)^2
else if (intervalEnd > double.MaxValue) else if (intervalEnd > double.MaxValue)
{ {
Func<double, double> u = (s) => Func<double, double> u = (s) => 2 * s * f(intervalBegin + (s / (1 - s)) * (s / (1 - s))) / ((1 - s) * (1 - s) * (1 - s));
{
return 2 * s * f(intervalBegin + (s / (1 - s)) * (s / (1 - s))) / ((1 - s) * (1 - s) * (1 - s));
};
return recursive_adaptive_integrate(u, 0, 1, maximumDepth, targetRelativeError, 0, out error, out L1Norm, gaussKronrodPoint); return recursive_adaptive_integrate(u, 0, 1, maximumDepth, targetRelativeError, 0, out error, out L1Norm, gaussKronrodPoint);
} }
// (-oo, b] => [-1, 0] // (-oo, b] => [-1, 0]
@ -134,10 +128,7 @@ namespace MathNet.Numerics.Integration
// g'(s) = 1 / (1 + s)^2 // g'(s) = 1 / (1 + s)^2
else if (intervalBegin < double.MinValue) else if (intervalBegin < double.MinValue)
{ {
Func<double, double> u = (s) => Func<double, double> u = (s) => -2 * s * f(intervalEnd - s / (1 + s) * (s / (1 + s))) / ((1 + s) * (1 + s) * (1 + s));
{
return -2 * s * f(intervalEnd - s / (1 + s) * (s / (1 + s))) / ((1 + s) * (1 + s) * (1 + s));
};
return recursive_adaptive_integrate(u, -1, 0, maximumDepth, targetRelativeError, 0, out error, out L1Norm, gaussKronrodPoint); return recursive_adaptive_integrate(u, -1, 0, maximumDepth, targetRelativeError, 0, out error, out L1Norm, gaussKronrodPoint);
} }
// [a, b] => [-1, 1] // [a, b] => [-1, 1]
@ -147,10 +138,7 @@ namespace MathNet.Numerics.Integration
// g'(t) = 3 / 4 * (b - a) * (1 - t^2) // g'(t) = 3 / 4 * (b - a) * (1 - t^2)
else else
{ {
Func<double, double> u = (t) => Func<double, double> u = (t) => f((intervalEnd - intervalBegin) / 4 * t * (3 - t * t) + (intervalEnd + intervalBegin) / 2) * 3 * (intervalEnd - intervalBegin) / 4 * (1 - t * t);
{
return f((intervalEnd - intervalBegin) / 4 * t * (3 - t * t) + (intervalEnd + intervalBegin) / 2) * 3 * (intervalEnd - intervalBegin) / 4 * (1 - t * t);
};
return recursive_adaptive_integrate(u, -1, 1, maximumDepth, targetRelativeError, 0d, out error, out L1Norm, gaussKronrodPoint); return recursive_adaptive_integrate(u, -1, 1, maximumDepth, targetRelativeError, 0d, out error, out L1Norm, gaussKronrodPoint);
} }
} }
@ -192,185 +180,174 @@ namespace MathNet.Numerics.Integration
// g'(t) = (1 + t^2) / (1 - t^2)^2 // g'(t) = (1 + t^2) / (1 - t^2)^2
if ((intervalBegin < double.MinValue) && (intervalEnd > double.MaxValue)) if ((intervalBegin < double.MinValue) && (intervalEnd > double.MaxValue))
{ {
Func<double, Complex> u = (t) => Func<double, Complex> u = (t) => f(t / (1 - t * t)) * (1 + t * t) / ((1 - t * t) * (1 - t * t));
{
return f(t / (1 - t * t)) * (1 + t * t) / ((1 - t * t) * (1 - t * t));
};
return contour_recursive_adaptive_integrate(u, -1, 1, maximumDepth, targetRelativeError, 0, out error, out L1Norm, gaussKronrodPoint); return contour_recursive_adaptive_integrate(u, -1, 1, maximumDepth, targetRelativeError, 0, out error, out L1Norm, gaussKronrodPoint);
} }
// [a, oo) => [0, 1] // [a, oo) => [0, 1]
// //
// integral_(a)^(oo) f(x) dx = integral_(0)^(oo) f(a + t^2) 2 t dt // integral_(a)^(oo) f(x) dx = integral_(0)^(oo) f(a + t^2) 2 t dt
// = integral_(0)^(1) f(a + g(s)^2) 2 g(s) g'(s) ds // = integral_(0)^(1) f(a + g(s)^2) 2 g(s) g'(s) ds
// g(s) = s / (1 - s) // g(s) = s / (1 - s)
// g'(s) = 1 / (1 - s)^2 // g'(s) = 1 / (1 - s)^2
else if (intervalEnd > double.MaxValue) if (intervalEnd > double.MaxValue)
{ {
Func<double, Complex> u = (s) => Func<double, Complex> u = (s) => 2 * s * f(intervalBegin + (s / (1 - s)) * (s / (1 - s))) / ((1 - s) * (1 - s) * (1 - s));
{
return 2 * s * f(intervalBegin + (s / (1 - s)) * (s / (1 - s))) / ((1 - s) * (1 - s) * (1 - s));
};
return contour_recursive_adaptive_integrate(u, 0, 1, maximumDepth, targetRelativeError, 0, out error, out L1Norm, gaussKronrodPoint); return contour_recursive_adaptive_integrate(u, 0, 1, maximumDepth, targetRelativeError, 0, out error, out L1Norm, gaussKronrodPoint);
} }
// (-oo, b] => [-1, 0] // (-oo, b] => [-1, 0]
// //
// integral_(-oo)^(b) f(x) dx = -integral_(-oo)^(0) f(b - t^2) 2 t dt // integral_(-oo)^(b) f(x) dx = -integral_(-oo)^(0) f(b - t^2) 2 t dt
// = -integral_(-1)^(0) f(b - g(s)^2) 2 g(s) g'(s) ds // = -integral_(-1)^(0) f(b - g(s)^2) 2 g(s) g'(s) ds
// g(s) = s / (1 + s) // g(s) = s / (1 + s)
// g'(s) = 1 / (1 + s)^2 // g'(s) = 1 / (1 + s)^2
else if (intervalBegin < double.MinValue) if (intervalBegin < double.MinValue)
{ {
Func<double, Complex> u = (s) => Func<double, Complex> u = (s) => -2 * s * f(intervalEnd - s / (1 + s) * (s / (1 + s))) / ((1 + s) * (1 + s) * (1 + s));
{
return -2 * s * f(intervalEnd - s / (1 + s) * (s / (1 + s))) / ((1 + s) * (1 + s) * (1 + s));
};
return contour_recursive_adaptive_integrate(u, -1, 0, maximumDepth, targetRelativeError, 0, out error, out L1Norm, gaussKronrodPoint); return contour_recursive_adaptive_integrate(u, -1, 0, maximumDepth, targetRelativeError, 0, out error, out L1Norm, gaussKronrodPoint);
} }
// [a, b] => [-1, 1] // [a, b] => [-1, 1]
// //
// integral_(a)^(b) f(x) dx = integral_(-1)^(1) f(g(t)) g'(t) dt // integral_(a)^(b) f(x) dx = integral_(-1)^(1) f(g(t)) g'(t) dt
// g(t) = (b - a) * t * (3 - t^2) / 4 + (b + a) / 2 // g(t) = (b - a) * t * (3 - t^2) / 4 + (b + a) / 2
// g'(t) = 3 / 4 * (b - a) * (1 - t^2) // g'(t) = 3 / 4 * (b - a) * (1 - t^2)
else
{ {
Func<double, Complex> u = (t) => Func<double, Complex> u = (t) => f((intervalEnd - intervalBegin) / 4 * t * (3 - t * t) + (intervalEnd + intervalBegin) / 2) * 3 * (intervalEnd - intervalBegin) / 4 * (1 - t * t);
{
return f((intervalEnd - intervalBegin) / 4 * t * (3 - t * t) + (intervalEnd + intervalBegin) / 2) * 3 * (intervalEnd - intervalBegin) / 4 * (1 - t * t);
};
return contour_recursive_adaptive_integrate(u, -1, 1, maximumDepth, targetRelativeError, 0d, out error, out L1Norm, gaussKronrodPoint); return contour_recursive_adaptive_integrate(u, -1, 1, maximumDepth, targetRelativeError, 0d, out error, out L1Norm, gaussKronrodPoint);
} }
} }
private static double integrate_non_adaptive_m1_1(Func<double, double> f, out double error, out double pL1, GaussPointPair gaussKronrodPoint) static double integrate_non_adaptive_m1_1(Func<double, double> f, out double error, out double pL1, GaussPointPair gaussKronrodPoint)
{ {
int gauss_start = 2; int gaussStart = 2;
int kronrod_start = 1; int kronrodStart = 1;
int gauss_order = (gaussKronrodPoint.Order - 1) / 2; int gaussOrder = (gaussKronrodPoint.Order - 1) / 2;
double kronrod_result = 0d; double kronrodResult = 0d;
double gauss_result = 0d; double gaussResult = 0d;
double fp, fm; double fp, fm;
var KAbscissa = gaussKronrodPoint.Abscissas; var KAbscissa = gaussKronrodPoint.Abscissas;
var KWeights = gaussKronrodPoint.Weights; var KWeights = gaussKronrodPoint.Weights;
var GWeights = gaussKronrodPoint.SecondWeights; var GWeights = gaussKronrodPoint.SecondWeights;
if ((gauss_order & 1) == 1) if ((gaussOrder & 1) == 1)
{ {
fp = f(0); fp = f(0);
kronrod_result = fp * KWeights[0]; kronrodResult = fp * KWeights[0];
gauss_result += fp * GWeights[0]; gaussResult += fp * GWeights[0];
} }
else else
{ {
fp = f(0); fp = f(0);
kronrod_result = fp * KWeights[0]; kronrodResult = fp * KWeights[0];
gauss_start = 1; gaussStart = 1;
kronrod_start = 2; kronrodStart = 2;
} }
double L1 = Math.Abs(kronrod_result); double L1 = Math.Abs(kronrodResult);
for (int i = gauss_start; i < KAbscissa.Length; i += 2) for (int i = gaussStart; i < KAbscissa.Length; i += 2)
{ {
fp = f(KAbscissa[i]); fp = f(KAbscissa[i]);
fm = f(-KAbscissa[i]); fm = f(-KAbscissa[i]);
kronrod_result += (fp + fm) * KWeights[i]; kronrodResult += (fp + fm) * KWeights[i];
L1 += (Math.Abs(fp) + Math.Abs(fm)) * KWeights[i]; L1 += (Math.Abs(fp) + Math.Abs(fm)) * KWeights[i];
gauss_result += (fp + fm) * GWeights[i / 2]; gaussResult += (fp + fm) * GWeights[i / 2];
} }
for (int i = kronrod_start; i < KAbscissa.Length; i += 2) for (int i = kronrodStart; i < KAbscissa.Length; i += 2)
{ {
fp = f(KAbscissa[i]); fp = f(KAbscissa[i]);
fm = f(-KAbscissa[i]); fm = f(-KAbscissa[i]);
kronrod_result += (fp + fm) * KWeights[i]; kronrodResult += (fp + fm) * KWeights[i];
L1 += (Math.Abs(fp) + Math.Abs(fm)) * KWeights[i]; L1 += (Math.Abs(fp) + Math.Abs(fm)) * KWeights[i];
} }
pL1 = L1; pL1 = L1;
error = Math.Max(Math.Abs(kronrod_result - gauss_result), Math.Abs(kronrod_result * Precision.MachineEpsilon * 2d)); error = Math.Max(Math.Abs(kronrodResult - gaussResult), Math.Abs(kronrodResult * Precision.MachineEpsilon * 2d));
return kronrod_result; return kronrodResult;
} }
private static Complex contour_integrate_non_adaptive_m1_1(Func<double, Complex> f, out double error, out double pL1, GaussPointPair gaussKronrodPoint) static Complex contour_integrate_non_adaptive_m1_1(Func<double, Complex> f, out double error, out double pL1, GaussPointPair gaussKronrodPoint)
{ {
int gauss_start = 2; int gaussStart = 2;
int kronrod_start = 1; int kronrodStart = 1;
int gauss_order = (gaussKronrodPoint.Order - 1) / 2; int gaussOrder = (gaussKronrodPoint.Order - 1) / 2;
Complex kronrod_result = new Complex(); Complex kronrodResult;
Complex gauss_result = new Complex(); Complex gaussResult = new Complex();
Complex fp, fm; Complex fp, fm;
var KAbscissa = gaussKronrodPoint.Abscissas; var KAbscissa = gaussKronrodPoint.Abscissas;
var KWeights = gaussKronrodPoint.Weights; var KWeights = gaussKronrodPoint.Weights;
var GWeights = gaussKronrodPoint.SecondWeights; var GWeights = gaussKronrodPoint.SecondWeights;
if (gauss_order.IsOdd()) if (gaussOrder.IsOdd())
{ {
fp = f(0); fp = f(0);
kronrod_result = fp * KWeights[0]; kronrodResult = fp * KWeights[0];
gauss_result += fp * GWeights[0]; gaussResult += fp * GWeights[0];
} }
else else
{ {
fp = f(0); fp = f(0);
kronrod_result = fp * KWeights[0]; kronrodResult = fp * KWeights[0];
gauss_start = 1; gaussStart = 1;
kronrod_start = 2; kronrodStart = 2;
} }
double L1 = Complex.Abs(kronrod_result); double L1 = Complex.Abs(kronrodResult);
for (int i = gauss_start; i < KAbscissa.Length; i += 2) for (int i = gaussStart; i < KAbscissa.Length; i += 2)
{ {
fp = f(KAbscissa[i]); fp = f(KAbscissa[i]);
fm = f(-KAbscissa[i]); fm = f(-KAbscissa[i]);
kronrod_result += (fp + fm) * KWeights[i]; kronrodResult += (fp + fm) * KWeights[i];
L1 += (Complex.Abs(fp) + Complex.Abs(fm)) * KWeights[i]; L1 += (Complex.Abs(fp) + Complex.Abs(fm)) * KWeights[i];
gauss_result += (fp + fm) * GWeights[i / 2]; gaussResult += (fp + fm) * GWeights[i / 2];
} }
for (int i = kronrod_start; i < KAbscissa.Length; i += 2) for (int i = kronrodStart; i < KAbscissa.Length; i += 2)
{ {
fp = f(KAbscissa[i]); fp = f(KAbscissa[i]);
fm = f(-KAbscissa[i]); fm = f(-KAbscissa[i]);
kronrod_result += (fp + fm) * KWeights[i]; kronrodResult += (fp + fm) * KWeights[i];
L1 += (Complex.Abs(fp) + Complex.Abs(fm)) * KWeights[i]; L1 += (Complex.Abs(fp) + Complex.Abs(fm)) * KWeights[i];
} }
pL1 = L1; pL1 = L1;
error = Math.Max(Complex.Abs(kronrod_result - gauss_result), Complex.Abs(kronrod_result * Precision.MachineEpsilon * 2d)); error = Math.Max(Complex.Abs(kronrodResult - gaussResult), Complex.Abs(kronrodResult * Precision.MachineEpsilon * 2d));
return kronrod_result; return kronrodResult;
} }
private static double recursive_adaptive_integrate(Func<double, double> f, double a, double b, int max_levels, double rel_tol, double abs_tol, out double error, out double L1, GaussPointPair gaussKronrodPoint) static double recursive_adaptive_integrate(Func<double, double> f, double a, double b, int maxLevels, double relTol, double absTol, out double error, out double L1, GaussPointPair gaussKronrodPoint)
{ {
double error_local;
double mean = (b + a) / 2; double mean = (b + a) / 2;
double scale = (b - a) / 2; double scale = (b - a) / 2;
var r1 = integrate_non_adaptive_m1_1((x) => f(scale * x + mean), out error_local, out L1, gaussKronrodPoint); var r1 = integrate_non_adaptive_m1_1((x) => f(scale * x + mean), out double errorLocal, out L1, gaussKronrodPoint);
var estimate = scale * r1; var estimate = scale * r1;
var tmp = estimate * rel_tol; var tmp = estimate * relTol;
var abs_tol1 = Math.Abs(tmp); var absTol1 = Math.Abs(tmp);
if (abs_tol == 0) if (absTol == 0)
{ {
abs_tol = abs_tol1; absTol = absTol1;
} }
if (max_levels > 0 && (abs_tol1 < error_local) && (abs_tol < error_local)) if (maxLevels > 0 && (absTol1 < errorLocal) && (absTol < errorLocal))
{ {
double mid = (a + b) / 2d; double mid = (a + b) / 2d;
double L1_local; double L1_local;
estimate = recursive_adaptive_integrate(f, a, mid, max_levels - 1, rel_tol, abs_tol / 2, out error, out L1, gaussKronrodPoint); estimate = recursive_adaptive_integrate(f, a, mid, maxLevels - 1, relTol, absTol / 2, out error, out L1, gaussKronrodPoint);
estimate += recursive_adaptive_integrate(f, mid, b, max_levels - 1, rel_tol, abs_tol / 2, out error_local, out L1_local, gaussKronrodPoint); estimate += recursive_adaptive_integrate(f, mid, b, maxLevels - 1, relTol, absTol / 2, out errorLocal, out L1_local, gaussKronrodPoint);
error += error_local; error += errorLocal;
L1 += L1_local; L1 += L1_local;
return estimate; return estimate;
} }
L1 *= scale; L1 *= scale;
error = error_local; error = errorLocal;
return estimate; return estimate;
} }
private static Complex contour_recursive_adaptive_integrate(Func<double, Complex> f, double a, double b, int max_levels, double rel_tol, double abs_tol, out double error, out double L1, GaussPointPair gaussKronrodPoint) static Complex contour_recursive_adaptive_integrate(Func<double, Complex> f, double a, double b, int maxLevels, double relTol, double absTol, out double error, out double L1, GaussPointPair gaussKronrodPoint)
{ {
double error_local; double error_local;
double mean = (b + a) / 2; double mean = (b + a) / 2;
@ -379,19 +356,19 @@ namespace MathNet.Numerics.Integration
var r1 = contour_integrate_non_adaptive_m1_1((x) => f(scale * x + mean), out error_local, out L1, gaussKronrodPoint); var r1 = contour_integrate_non_adaptive_m1_1((x) => f(scale * x + mean), out error_local, out L1, gaussKronrodPoint);
var estimate = scale * r1; var estimate = scale * r1;
var tmp = estimate * rel_tol; var tmp = estimate * relTol;
var abs_tol1 = Complex.Abs(tmp); var absTol1 = Complex.Abs(tmp);
if (abs_tol == 0) if (absTol == 0)
{ {
abs_tol = abs_tol1; absTol = absTol1;
} }
if (max_levels > 0 && (abs_tol1 < error_local) && (abs_tol < error_local)) if (maxLevels > 0 && (absTol1 < error_local) && (absTol < error_local))
{ {
double mid = (a + b) / 2d; double mid = (a + b) / 2d;
double L1_local; double L1_local;
estimate = contour_recursive_adaptive_integrate(f, a, mid, max_levels - 1, rel_tol, abs_tol / 2, out error, out L1, gaussKronrodPoint); estimate = contour_recursive_adaptive_integrate(f, a, mid, maxLevels - 1, relTol, absTol / 2, out error, out L1, gaussKronrodPoint);
estimate += contour_recursive_adaptive_integrate(f, mid, b, max_levels - 1, rel_tol, abs_tol / 2, out error_local, out L1_local, gaussKronrodPoint); estimate += contour_recursive_adaptive_integrate(f, mid, b, maxLevels - 1, relTol, absTol / 2, out error_local, out L1_local, gaussKronrodPoint);
error += error_local; error += error_local;
L1 += L1_local; L1 += L1_local;
return estimate; return estimate;

2
src/Numerics/Integration/GaussLegendreRule.cs

@ -38,7 +38,7 @@ namespace MathNet.Numerics.Integration
/// </summary> /// </summary>
public class GaussLegendreRule public class GaussLegendreRule
{ {
private readonly GaussPoint _gaussLegendrePoint; readonly GaussPoint _gaussLegendrePoint;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="GaussLegendreRule"/> class. /// Initializes a new instance of the <see cref="GaussLegendreRule"/> class.

37
src/Numerics/Integration/GaussRule/GaussKronrodPoint.cs

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics;
namespace MathNet.Numerics.Integration.GaussRule namespace MathNet.Numerics.Integration.GaussRule
{ {
@ -389,7 +388,7 @@ namespace MathNet.Numerics.Integration.GaussRule
// Calculate Kronrod polynomial in terms of Legendre polynomials // Calculate Kronrod polynomial in terms of Legendre polynomials
// K(x) = c0*P(0, x) + c1*P(1, x) + ... // K(x) = c0*P(0, x) + c1*P(1, x) + ...
var c = StieltjesP(gaussOrder + 1); var c = StieltjesP(gaussOrder + 1);
// Calculate Abscissas for Kronrod polynomial // Calculate Abscissas for Kronrod polynomial
@ -420,7 +419,7 @@ namespace MathNet.Numerics.Integration.GaussRule
// Concatenate two abscissas // Concatenate two abscissas
var abscissas = new double[gaussAbscissas.Length + kronrodAbscissas.Length]; var abscissas = new double[gaussAbscissas.Length + kronrodAbscissas.Length];
gaussAbscissas.CopyTo(abscissas, 0); gaussAbscissas.CopyTo(abscissas, 0);
kronrodAbscissas.CopyTo(abscissas, gaussAbscissas.Length); kronrodAbscissas.CopyTo(abscissas, gaussAbscissas.Length);
abscissas = abscissas.OrderBy(v => v).ToArray(); abscissas = abscissas.OrderBy(v => v).ToArray();
@ -454,9 +453,9 @@ namespace MathNet.Numerics.Integration.GaussRule
/// <summary> /// <summary>
/// Returns coefficients of a Stieltjes polynomial in terms of Legendre polynomials. /// Returns coefficients of a Stieltjes polynomial in terms of Legendre polynomials.
/// </summary> /// </summary>
internal static double[] StieltjesP(int order) static double[] StieltjesP(int order)
{ {
// Reference: // Reference:
// 1. Patterson, Thomas NL. "The optimum addition of points to quadrature formulae." Mathematics of Computation 22.104 (1968): 847-856. // 1. Patterson, Thomas NL. "The optimum addition of points to quadrature formulae." Mathematics of Computation 22.104 (1968): 847-856.
// 2. Piessens, Robert, and Maria Branders. "A note on the optimal addition of abscissas to quadrature formulas of Gauss and Lobatto type." Mathematics of Computation (1974): 135-139. // 2. Piessens, Robert, and Maria Branders. "A note on the optimal addition of abscissas to quadrature formulas of Gauss and Lobatto type." Mathematics of Computation (1974): 135-139.
// 3. Legendre-Stieltjes Polynomials, Boost.Math // 3. Legendre-Stieltjes Polynomials, Boost.Math
@ -475,14 +474,14 @@ namespace MathNet.Numerics.Integration.GaussRule
// The added n + 1 Kronrod abscissae is the roots of the Kronrod polynomial. // The added n + 1 Kronrod abscissae is the roots of the Kronrod polynomial.
if (order == 1) // P(1, x) if (order == 1) // P(1, x)
return new double[] { 0, 1 }; return new double[] { 0, 1 };
else if (order == 2) // -2/5 * P(0, x) + P(2, x) if (order == 2) // -2/5 * P(0, x) + P(2, x)
return new double[] { -0.4, 0, 1 }; return new double[] { -0.4, 0, 1 };
else if (order == 3) // -9/14 * P(1, x) + P(3, x) if (order == 3) // -9/14 * P(1, x) + P(3, x)
return new double[] { 0, -0.642857142857142857142857142857, 0, 1 }; return new double[] { 0, -0.642857142857142857142857142857, 0, 1 };
else if (order == 4) // 14/891 * P(0, x) - 20/27 * P(2, x) + P(4, x) if (order == 4) // 14/891 * P(0, x) - 20/27 * P(2, x) + P(4, x)
return new double[] { 0.0157126823793490460157126823793, 0, -0.740740740740740740740740740741, 0, 1 }; return new double[] { 0.0157126823793490460157126823793, 0, -0.740740740740740740740740740741, 0, 1 };
else if (order == 5) // 135/12584 * P(1, x) - 35/44 * P(3, x) + P(5, x) if (order == 5) // 135/12584 * P(1, x) - 35/44 * P(3, x) + P(5, x)
return new double[] { 0, 0.0107279084551811824539097266370, 0, -0.795454545454545454545454545455, 0, 1 }; return new double[] { 0, 0.0107279084551811824539097266370, 0, -0.795454545454545454545454545455, 0, 1 };
int n = order - 1; int n = order - 1;
@ -498,7 +497,7 @@ namespace MathNet.Numerics.Integration.GaussRule
// a[r - 2] = -a[r] * S[r, 2] / S[r - 2, 2] - a[r - 1] * S[r - 1, 2] / S[r - 2, 2]; // a[r - 2] = -a[r] * S[r, 2] / S[r - 2, 2] - a[r - 1] * S[r - 1, 2] / S[r - 2, 2];
// ... // ...
// a[1] = -a[r] * S[r, r - 1] / S[1, r - 1] - a[r - 1] * S[r - 1, r - 1] / S[1, r - 1] - ... - a[2] * S[2, r - 1] / S[1, r - 1]; // a[1] = -a[r] * S[r, r - 1] / S[1, r - 1] - a[r - 1] * S[r - 1, r - 1] / S[1, r - 1] - ... - a[2] * S[2, r - 1] / S[1, r - 1];
// //
// S[i, k] / S[r - k, k] = S[i - 1, k] / S[r - k, k] // S[i, k] / S[r - k, k] = S[i - 1, k] / S[r - k, k]
// * ((n - q + 2 * (i + k - 1)) * (n + q + 2 * (k - i + 1)) * (n - 1 - q + 2 * (i - k)) * (2 * (k + i - 1) - 1 - q - n)) // * ((n - q + 2 * (i + k - 1)) * (n + q + 2 * (k - i + 1)) * (n - 1 - q + 2 * (i - k)) * (2 * (k + i - 1) - 1 - q - n))
// / ((n - q + 2 * (i - k)) * (2 * (k + i - 1) - q - n) * (n + 1 + q + 2 * (k - i)) * (n - 1 - q + 2 * (i + k))); // / ((n - q + 2 * (i - k)) * (2 * (k + i - 1) - q - n) * (n + 1 + q + 2 * (k - i)) * (n - 1 - q + 2 * (i + k)));
@ -513,11 +512,11 @@ namespace MathNet.Numerics.Integration.GaussRule
double numerator = (n - q + 2 * (i + k - 1)) * (n + q + 2 * (k - i + 1)) * (n - 1 - q + 2 * (i - k)) * (2 * (k + i - 1) - 1 - q - n); double numerator = (n - q + 2 * (i + k - 1)) * (n + q + 2 * (k - i + 1)) * (n - 1 - q + 2 * (i - k)) * (2 * (k + i - 1) - 1 - q - n);
double denominator = (n - q + 2 * (i - k)) * (2 * (k + i - 1) - q - n) * (n + 1 + q + 2 * (k - i)) * (n - 1 - q + 2 * (i + k)); double denominator = (n - q + 2 * (i - k)) * (2 * (k + i - 1) - q - n) * (n + 1 + q + 2 * (k - i)) * (n - 1 - q + 2 * (i + k));
ratio = ratio * numerator / denominator; ratio = ratio * numerator / denominator;
a[r - k] -= a[i] * ratio; a[r - k] -= a[i] * ratio;
} }
} }
// K = sum c[k] P[k, x] // K = sum c[k] P[k, x]
double[] c = new double[2 * r - q]; double[] c = new double[2 * r - q];
for (int i = 1; i < a.Length; i++) for (int i = 1; i < a.Length; i++)
@ -531,22 +530,22 @@ namespace MathNet.Numerics.Integration.GaussRule
/// <summary> /// <summary>
/// Return value and derivative of a Legendre series at given points. /// Return value and derivative of a Legendre series at given points.
/// </summary> /// </summary>
internal static Tuple<double, double> LegendreSeries(double[] a, double x) static Tuple<double, double> LegendreSeries(double[] a, double x)
{ {
// S = a[0]*P[0, x] + ... + a[k]*P[k, x] + ... + a[n]*P[n, x] // S = a[0]*P[0, x] + ... + a[k]*P[k, x] + ... + a[n]*P[n, x]
// where P[k, x] is the Legendre polynomial of order k // where P[k, x] is the Legendre polynomial of order k
// //
// According to the Clenshaw algorithm, S can be written by // According to the Clenshaw algorithm, S can be written by
// S = a[0] + x*b[1, x] - 1/2 * b[2,x] // S = a[0] + x*b[1, x] - 1/2 * b[2,x]
// //
// b[n + 1, x] = 0 // b[n + 1, x] = 0
// b[n + 2, x] = 0 // b[n + 2, x] = 0
// b[k, x] = a[k] + (2k + 1)/(k + 1)*x*b[k + 1, x] - (k + 1)/(k + 2)*b[k + 2, x] // b[k, x] = a[k] + (2k + 1)/(k + 1)*x*b[k + 1, x] - (k + 1)/(k + 2)*b[k + 2, x]
// //
// Derivative of S is given by // Derivative of S is given by
// S' = b[1, x] + x*b'[1, x] - 1/2 * b'[2,x] // S' = b[1, x] + x*b'[1, x] - 1/2 * b'[2,x]
// //
// b'[k, x] = (2k + 1)/(k + 1)*b[k + 1, x] + (2k + 1)/(k + 1)*x*b'[k + 1, x] - (k + 1)/(k + 2)*b'[k + 2, x] // b'[k, x] = (2k + 1)/(k + 1)*b[k + 1, x] + (2k + 1)/(k + 1)*x*b'[k + 1, x] - (k + 1)/(k + 2)*b'[k + 2, x]
if (a.Length == 1) if (a.Length == 1)
return new Tuple<double, double>(a[0], 0); return new Tuple<double, double>(a[0], 0);
@ -576,7 +575,7 @@ namespace MathNet.Numerics.Integration.GaussRule
/// <summary> /// <summary>
/// Return value and derivative of a Legendre polynomial of order at given points. /// Return value and derivative of a Legendre polynomial of order at given points.
/// </summary> /// </summary>
internal static Tuple<double, double> LegendreP(int order, double x) static Tuple<double, double> LegendreP(int order, double x)
{ {
// The Legendre polynomial, P[n, x], is defined by the recurrence relation: // The Legendre polynomial, P[n, x], is defined by the recurrence relation:
// //
@ -602,7 +601,7 @@ namespace MathNet.Numerics.Integration.GaussRule
{ {
b0 = (2.0 * k - 1.0) / k * x * b1 - (k - 1.0) / k * b2; // L(k, x) b0 = (2.0 * k - 1.0) / k * x * b1 - (k - 1.0) / k * b2; // L(k, x)
p0 = (2.0 * k - 1.0) / k * (b1 + x * p1) - (k - 1.0) / k * p2; // L'(k, x) p0 = (2.0 * k - 1.0) / k * (b1 + x * p1) - (k - 1.0) / k * p2; // L'(k, x)
b2 = b1; b2 = b1;
b1 = b0; b1 = b0;
p2 = p1; p2 = p1;

12
src/Numerics/Integration/GaussRule/GaussKronrodPointFactory.cs

@ -8,7 +8,7 @@ namespace MathNet.Numerics.Integration.GaussRule
internal static class GaussKronrodPointFactory internal static class GaussKronrodPointFactory
{ {
[ThreadStatic] [ThreadStatic]
private static GaussPointPair gaussKronrodPoint; static GaussPointPair _gaussKronrodPoint;
/// <summary> /// <summary>
/// Getter for the GaussKronrodPoint. /// Getter for the GaussKronrodPoint.
@ -18,17 +18,17 @@ namespace MathNet.Numerics.Integration.GaussRule
public static GaussPointPair GetGaussPoint(int order) public static GaussPointPair GetGaussPoint(int order)
{ {
// Try to get the GaussKronrodPoint from the cached static field. // Try to get the GaussKronrodPoint from the cached static field.
bool gaussKronrodPointIsCached = gaussKronrodPoint != null && gaussKronrodPoint.Order == order; bool gaussKronrodPointIsCached = _gaussKronrodPoint != null && _gaussKronrodPoint.Order == order;
if (!gaussKronrodPointIsCached) if (!gaussKronrodPointIsCached)
{ {
// Try to find the GaussKronrodPoint in the precomputed dictionary. // Try to find the GaussKronrodPoint in the precomputed dictionary.
if (!GaussKronrodPoint.PreComputed.TryGetValue(order, out gaussKronrodPoint)) if (!GaussKronrodPoint.PreComputed.TryGetValue(order, out _gaussKronrodPoint))
{ {
gaussKronrodPoint = GaussKronrodPoint.Generate(order, 1E-10); _gaussKronrodPoint = GaussKronrodPoint.Generate(order, 1E-10);
} }
} }
return gaussKronrodPoint; return _gaussKronrodPoint;
} }
} }
} }

4
src/Numerics/Integration/GaussRule/GaussLegendrePointFactory.cs

@ -37,7 +37,7 @@ namespace MathNet.Numerics.Integration.GaussRule
internal static class GaussLegendrePointFactory internal static class GaussLegendrePointFactory
{ {
[ThreadStatic] [ThreadStatic]
private static GaussPoint _gaussLegendrePoint; static GaussPoint _gaussLegendrePoint;
/// <summary> /// <summary>
/// Getter for the GaussPoint. /// Getter for the GaussPoint.
@ -79,7 +79,7 @@ namespace MathNet.Numerics.Integration.GaussRule
/// <param name="intervalEnd">Where the interval stops, inclusive and finite.</param> /// <param name="intervalEnd">Where the interval stops, inclusive and finite.</param>
/// <param name="gaussPoint">Object containing the non-negative abscissas/weights, order, and intervalBegin/intervalEnd. The non-negative abscissas/weights are generated over the interval [-1,1] for the given order.</param> /// <param name="gaussPoint">Object containing the non-negative abscissas/weights, order, and intervalBegin/intervalEnd. The non-negative abscissas/weights are generated over the interval [-1,1] for the given order.</param>
/// <returns>Object containing the abscissas/weights, order, and intervalBegin/intervalEnd.</returns> /// <returns>Object containing the abscissas/weights, order, and intervalBegin/intervalEnd.</returns>
private static GaussPoint Map(double intervalBegin, double intervalEnd, GaussPoint gaussPoint) static GaussPoint Map(double intervalBegin, double intervalEnd, GaussPoint gaussPoint)
{ {
double[] abscissas = new double[gaussPoint.Order]; double[] abscissas = new double[gaussPoint.Order];
double[] weights = new double[gaussPoint.Order]; double[] weights = new double[gaussPoint.Order];

12
src/Numerics/Integration/GaussRule/GaussPoint.cs

@ -34,15 +34,15 @@ namespace MathNet.Numerics.Integration.GaussRule
/// </summary> /// </summary>
internal class GaussPoint internal class GaussPoint
{ {
internal double[] Abscissas { get; private set; } internal double[] Abscissas { get; }
internal double[] Weights { get; private set; } internal double[] Weights { get; }
internal double IntervalBegin { get; private set; } internal double IntervalBegin { get; }
internal double IntervalEnd { get; private set; } internal double IntervalEnd { get; }
internal int Order { get; private set; } internal int Order { get; }
internal GaussPoint(double intervalBegin, double intervalEnd, int order, double[] abscissas, double[] weights) internal GaussPoint(double intervalBegin, double intervalEnd, int order, double[] abscissas, double[] weights)
{ {
@ -57,4 +57,4 @@ namespace MathNet.Numerics.Integration.GaussRule
{ {
} }
} }
} }

20
src/Numerics/Integration/GaussRule/GaussPointPair.cs

@ -5,21 +5,21 @@
/// </summary> /// </summary>
internal class GaussPointPair internal class GaussPointPair
{ {
internal int Order { get; private set; } internal int Order { get; }
internal double[] Abscissas { get; private set; } internal double[] Abscissas { get; }
internal double[] Weights { get; private set; } internal double[] Weights { get; }
internal int SecondOrder { get; private set; }
internal double[] SecondAbscissas { get; private set; } internal int SecondOrder { get; }
internal double[] SecondWeights { get; private set; } internal double[] SecondAbscissas { get; }
internal double IntervalBegin { get; private set; } internal double[] SecondWeights { get; }
internal double IntervalEnd { get; private set; } internal double IntervalBegin { get; }
internal double IntervalEnd { get; }
internal GaussPointPair(double intervalBegin, double intervalEnd, int order, double[] abscissas, double[] weights, int secondOrder, double[] secondAbscissas, double[] secondWeights) internal GaussPointPair(double intervalBegin, double intervalEnd, int order, double[] abscissas, double[] weights, int secondOrder, double[] secondAbscissas, double[] secondWeights)
{ {
@ -30,7 +30,7 @@
Weights = weights; Weights = weights;
SecondOrder = secondOrder; SecondOrder = secondOrder;
SecondAbscissas = secondAbscissas; SecondAbscissas = secondAbscissas;
SecondWeights = secondWeights; SecondWeights = secondWeights;
} }
internal GaussPointPair(int order, double[] abscissas, double[] weights, int secondOrder, double[] secondWeights) internal GaussPointPair(int order, double[] abscissas, double[] weights, int secondOrder, double[] secondWeights)

2
src/Numerics/Interpolate.cs

@ -156,7 +156,7 @@ namespace MathNet.Numerics
/// </remarks> /// </remarks>
public static IInterpolation Linear(IEnumerable<double> points, IEnumerable<double> values) public static IInterpolation Linear(IEnumerable<double> points, IEnumerable<double> values)
{ {
return Interpolation.LinearSpline.Interpolate(points, values); return LinearSpline.Interpolate(points, values);
} }
/// <summary> /// <summary>

20
src/Numerics/Interpolation/Barycentric.cs

@ -325,38 +325,26 @@ namespace MathNet.Numerics.Interpolation
/// </summary> /// </summary>
/// <param name="t">Point t to interpolate at.</param> /// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated first derivative at point t.</returns> /// <returns>Interpolated first derivative at point t.</returns>
double IInterpolation.Differentiate(double t) double IInterpolation.Differentiate(double t) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
/// <summary> /// <summary>
/// Differentiate twice at point t. NOT SUPPORTED. /// Differentiate twice at point t. NOT SUPPORTED.
/// </summary> /// </summary>
/// <param name="t">Point t to interpolate at.</param> /// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated second derivative at point t.</returns> /// <returns>Interpolated second derivative at point t.</returns>
double IInterpolation.Differentiate2(double t) double IInterpolation.Differentiate2(double t) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
/// <summary> /// <summary>
/// Indefinite integral at point t. NOT SUPPORTED. /// Indefinite integral at point t. NOT SUPPORTED.
/// </summary> /// </summary>
/// <param name="t">Point t to integrate at.</param> /// <param name="t">Point t to integrate at.</param>
double IInterpolation.Integrate(double t) double IInterpolation.Integrate(double t) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
/// <summary> /// <summary>
/// Definite integral between points a and b. NOT SUPPORTED. /// Definite integral between points a and b. NOT SUPPORTED.
/// </summary> /// </summary>
/// <param name="a">Left bound of the integration interval [a,b].</param> /// <param name="a">Left bound of the integration interval [a,b].</param>
/// <param name="b">Right bound of the integration interval [a,b].</param> /// <param name="b">Right bound of the integration interval [a,b].</param>
double IInterpolation.Integrate(double a, double b) double IInterpolation.Integrate(double a, double b) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
} }
} }

20
src/Numerics/Interpolation/BulirschStoerRationalInterpolation.cs

@ -173,38 +173,26 @@ namespace MathNet.Numerics.Interpolation
/// </summary> /// </summary>
/// <param name="t">Point t to interpolate at.</param> /// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated first derivative at point t.</returns> /// <returns>Interpolated first derivative at point t.</returns>
double IInterpolation.Differentiate(double t) double IInterpolation.Differentiate(double t) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
/// <summary> /// <summary>
/// Differentiate twice at point t. NOT SUPPORTED. /// Differentiate twice at point t. NOT SUPPORTED.
/// </summary> /// </summary>
/// <param name="t">Point t to interpolate at.</param> /// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated second derivative at point t.</returns> /// <returns>Interpolated second derivative at point t.</returns>
double IInterpolation.Differentiate2(double t) double IInterpolation.Differentiate2(double t) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
/// <summary> /// <summary>
/// Indefinite integral at point t. NOT SUPPORTED. /// Indefinite integral at point t. NOT SUPPORTED.
/// </summary> /// </summary>
/// <param name="t">Point t to integrate at.</param> /// <param name="t">Point t to integrate at.</param>
double IInterpolation.Integrate(double t) double IInterpolation.Integrate(double t) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
/// <summary> /// <summary>
/// Definite integral between points a and b. NOT SUPPORTED. /// Definite integral between points a and b. NOT SUPPORTED.
/// </summary> /// </summary>
/// <param name="a">Left bound of the integration interval [a,b].</param> /// <param name="a">Left bound of the integration interval [a,b].</param>
/// <param name="b">Right bound of the integration interval [a,b].</param> /// <param name="b">Right bound of the integration interval [a,b].</param>
double IInterpolation.Integrate(double a, double b) double IInterpolation.Integrate(double a, double b) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
} }
} }

9
src/Numerics/Interpolation/CubicSpline.cs

@ -229,7 +229,7 @@ namespace MathNet.Numerics.Interpolation
} }
var m = new double[x.Length - 1]; var m = new double[x.Length - 1];
for (int i = 0; i < m.Length; i++) for (int i = 0; i < m.Length; i++)
{ {
m[i] = (y[i + 1] - y[i])/(x[i + 1] - x[i]); m[i] = (y[i + 1] - y[i])/(x[i + 1] - x[i]);
@ -259,7 +259,7 @@ namespace MathNet.Numerics.Interpolation
hPrev = h; hPrev = h;
mPrevIs0 = mIs0; mPrevIs0 = mIs0;
} }
// Special case end-points. // Special case end-points.
dd[0] = PchipEndPoints(x[1] - x[0], x[2] - x[1], m[0], m[1]); dd[0] = PchipEndPoints(x[1] - x[0], x[2] - x[1], m[0], m[1]);
dd[dd.Length - 1] = PchipEndPoints( dd[dd.Length - 1] = PchipEndPoints(
@ -595,10 +595,7 @@ namespace MathNet.Numerics.Interpolation
/// </summary> /// </summary>
/// <param name="a">Left bound of the integration interval [a,b].</param> /// <param name="a">Left bound of the integration interval [a,b].</param>
/// <param name="b">Right bound of the integration interval [a,b].</param> /// <param name="b">Right bound of the integration interval [a,b].</param>
public double Integrate(double a, double b) public double Integrate(double a, double b) => Integrate(b) - Integrate(a);
{
return Integrate(b) - Integrate(a);
}
double[] ComputeIndefiniteIntegral() double[] ComputeIndefiniteIntegral()
{ {

10
src/Numerics/Interpolation/LinearSpline.cs

@ -150,10 +150,7 @@ namespace MathNet.Numerics.Interpolation
/// </summary> /// </summary>
/// <param name="t">Point t to interpolate at.</param> /// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated second derivative at point t.</returns> /// <returns>Interpolated second derivative at point t.</returns>
public double Differentiate2(double t) public double Differentiate2(double t) => 0d;
{
return 0d;
}
/// <summary> /// <summary>
/// Indefinite integral at point t. /// Indefinite integral at point t.
@ -171,10 +168,7 @@ namespace MathNet.Numerics.Interpolation
/// </summary> /// </summary>
/// <param name="a">Left bound of the integration interval [a,b].</param> /// <param name="a">Left bound of the integration interval [a,b].</param>
/// <param name="b">Right bound of the integration interval [a,b].</param> /// <param name="b">Right bound of the integration interval [a,b].</param>
public double Integrate(double a, double b) public double Integrate(double a, double b) => Integrate(b) - Integrate(a);
{
return Integrate(b) - Integrate(a);
}
double[] ComputeIndefiniteIntegral() double[] ComputeIndefiniteIntegral()
{ {

10
src/Numerics/Interpolation/LogLinear.cs

@ -156,19 +156,13 @@ namespace MathNet.Numerics.Interpolation
/// Indefinite integral at point t. /// Indefinite integral at point t.
/// </summary> /// </summary>
/// <param name="t">Point t to integrate at.</param> /// <param name="t">Point t to integrate at.</param>
double IInterpolation.Integrate(double t) double IInterpolation.Integrate(double t) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
/// <summary> /// <summary>
/// Definite integral between points a and b. /// Definite integral between points a and b.
/// </summary> /// </summary>
/// <param name="a">Left bound of the integration interval [a,b].</param> /// <param name="a">Left bound of the integration interval [a,b].</param>
/// <param name="b">Right bound of the integration interval [a,b].</param> /// <param name="b">Right bound of the integration interval [a,b].</param>
double IInterpolation.Integrate(double a, double b) double IInterpolation.Integrate(double a, double b) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
} }
} }

10
src/Numerics/Interpolation/NevillePolynomialInterpolation.cs

@ -201,19 +201,13 @@ namespace MathNet.Numerics.Interpolation
/// Indefinite integral at point t. NOT SUPPORTED. /// Indefinite integral at point t. NOT SUPPORTED.
/// </summary> /// </summary>
/// <param name="t">Point t to integrate at.</param> /// <param name="t">Point t to integrate at.</param>
double IInterpolation.Integrate(double t) double IInterpolation.Integrate(double t) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
/// <summary> /// <summary>
/// Definite integral between points a and b. NOT SUPPORTED. /// Definite integral between points a and b. NOT SUPPORTED.
/// </summary> /// </summary>
/// <param name="a">Left bound of the integration interval [a,b].</param> /// <param name="a">Left bound of the integration interval [a,b].</param>
/// <param name="b">Right bound of the integration interval [a,b].</param> /// <param name="b">Right bound of the integration interval [a,b].</param>
double IInterpolation.Integrate(double a, double b) double IInterpolation.Integrate(double a, double b) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
} }
} }

5
src/Numerics/Interpolation/QuadraticSpline.cs

@ -126,10 +126,7 @@ namespace MathNet.Numerics.Interpolation
/// </summary> /// </summary>
/// <param name="a">Left bound of the integration interval [a,b].</param> /// <param name="a">Left bound of the integration interval [a,b].</param>
/// <param name="b">Right bound of the integration interval [a,b].</param> /// <param name="b">Right bound of the integration interval [a,b].</param>
public double Integrate(double a, double b) public double Integrate(double a, double b) => Integrate(b) - Integrate(a);
{
return Integrate(b) - Integrate(a);
}
double[] ComputeIndefiniteIntegral() double[] ComputeIndefiniteIntegral()
{ {

10
src/Numerics/Interpolation/StepInterpolation.cs

@ -137,10 +137,7 @@ namespace MathNet.Numerics.Interpolation
/// </summary> /// </summary>
/// <param name="t">Point t to interpolate at.</param> /// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated second derivative at point t.</returns> /// <returns>Interpolated second derivative at point t.</returns>
public double Differentiate2(double t) public double Differentiate2(double t) => Differentiate(t);
{
return Differentiate(t);
}
/// <summary> /// <summary>
/// Indefinite integral at point t. /// Indefinite integral at point t.
@ -163,10 +160,7 @@ namespace MathNet.Numerics.Interpolation
/// </summary> /// </summary>
/// <param name="a">Left bound of the integration interval [a,b].</param> /// <param name="a">Left bound of the integration interval [a,b].</param>
/// <param name="b">Right bound of the integration interval [a,b].</param> /// <param name="b">Right bound of the integration interval [a,b].</param>
public double Integrate(double a, double b) public double Integrate(double a, double b) => Integrate(b) - Integrate(a);
{
return Integrate(b) - Integrate(a);
}
double[] ComputeIndefiniteIntegral() double[] ComputeIndefiniteIntegral()
{ {

25
src/Numerics/Interpolation/TransformedInterpolation.cs

@ -130,48 +130,33 @@ namespace MathNet.Numerics.Interpolation
/// </summary> /// </summary>
/// <param name="t">Point t to interpolate at.</param> /// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated value x(t).</returns> /// <returns>Interpolated value x(t).</returns>
public double Interpolate(double t) public double Interpolate(double t) => _transform(_interpolation.Interpolate(t));
{
return _transform(_interpolation.Interpolate(t));
}
/// <summary> /// <summary>
/// Differentiate at point t. NOT SUPPORTED. /// Differentiate at point t. NOT SUPPORTED.
/// </summary> /// </summary>
/// <param name="t">Point t to interpolate at.</param> /// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated first derivative at point t.</returns> /// <returns>Interpolated first derivative at point t.</returns>
double IInterpolation.Differentiate(double t) double IInterpolation.Differentiate(double t) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
/// <summary> /// <summary>
/// Differentiate twice at point t. NOT SUPPORTED. /// Differentiate twice at point t. NOT SUPPORTED.
/// </summary> /// </summary>
/// <param name="t">Point t to interpolate at.</param> /// <param name="t">Point t to interpolate at.</param>
/// <returns>Interpolated second derivative at point t.</returns> /// <returns>Interpolated second derivative at point t.</returns>
double IInterpolation.Differentiate2(double t) double IInterpolation.Differentiate2(double t) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
/// <summary> /// <summary>
/// Indefinite integral at point t. NOT SUPPORTED. /// Indefinite integral at point t. NOT SUPPORTED.
/// </summary> /// </summary>
/// <param name="t">Point t to integrate at.</param> /// <param name="t">Point t to integrate at.</param>
double IInterpolation.Integrate(double t) double IInterpolation.Integrate(double t) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
/// <summary> /// <summary>
/// Definite integral between points a and b. NOT SUPPORTED. /// Definite integral between points a and b. NOT SUPPORTED.
/// </summary> /// </summary>
/// <param name="a">Left bound of the integration interval [a,b].</param> /// <param name="a">Left bound of the integration interval [a,b].</param>
/// <param name="b">Right bound of the integration interval [a,b].</param> /// <param name="b">Right bound of the integration interval [a,b].</param>
double IInterpolation.Integrate(double a, double b) double IInterpolation.Integrate(double a, double b) => throw new NotSupportedException();
{
throw new NotSupportedException();
}
} }
} }

4
src/Numerics/LinearAlgebra/Builder.cs

@ -1622,8 +1622,8 @@ namespace MathNet.Numerics.LinearAlgebra
if (typeof (T) == typeof (System.Numerics.Complex)) if (typeof (T) == typeof (System.Numerics.Complex))
{ {
return new Tuple<MatrixBuilder<T>, VectorBuilder<T>>( return new Tuple<MatrixBuilder<T>, VectorBuilder<T>>(
(MatrixBuilder<T>)(object)new LinearAlgebra.Complex.MatrixBuilder(), (MatrixBuilder<T>)(object)new Complex.MatrixBuilder(),
(VectorBuilder<T>)(object)new LinearAlgebra.Complex.VectorBuilder()); (VectorBuilder<T>)(object)new Complex.VectorBuilder());
} }
if (typeof (T) == typeof (Numerics.Complex32)) if (typeof (T) == typeof (Numerics.Complex32))

2
src/Numerics/LinearAlgebra/Complex/Factorization/DenseGramSchmidt.cs

@ -78,7 +78,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
/// <param name="rowsQ">Number of rows in <see cref="Matrix{T}"/> Q.</param> /// <param name="rowsQ">Number of rows in <see cref="Matrix{T}"/> Q.</param>
/// <param name="columnsQ">Number of columns in <see cref="Matrix{T}"/> Q.</param> /// <param name="columnsQ">Number of columns in <see cref="Matrix{T}"/> Q.</param>
/// <param name="r">On exit is filled by <see cref="Matrix{T}"/> R.</param> /// <param name="r">On exit is filled by <see cref="Matrix{T}"/> R.</param>
private static void Factorize(Complex[] q, int rowsQ, int columnsQ, Complex[] r) static void Factorize(Complex[] q, int rowsQ, int columnsQ, Complex[] r)
{ {
for (var k = 0; k < columnsQ; k++) for (var k = 0; k < columnsQ; k++)
{ {

2
src/Numerics/LinearAlgebra/Complex/Matrix.cs

@ -455,7 +455,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
protected override void DoPointwiseAbs(Matrix<Complex> result) protected override void DoPointwiseAbs(Matrix<Complex> result)
{ {
Map(x => (Complex)Complex.Abs(x), result, Zeros.AllowSkip); Map(x => Complex.Abs(x), result, Zeros.AllowSkip);
} }
protected override void DoPointwiseAcos(Matrix<Complex> result) protected override void DoPointwiseAcos(Matrix<Complex> result)
{ {

14
src/Numerics/LinearAlgebra/Complex/Solvers/ILUTPPreconditioner.cs

@ -714,7 +714,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="upperBound">The stopping index.</param> /// <param name="upperBound">The stopping index.</param>
/// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param> /// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param>
/// <param name="values">The <see cref="Vector{T}"/> that contains the values that need to be sorted.</param> /// <param name="values">The <see cref="Vector{T}"/> that contains the values that need to be sorted.</param>
private static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector<Complex> values) static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector<Complex> values)
{ {
var start = ((upperBound - lowerBound + 1) / 2) - 1 + lowerBound; var start = ((upperBound - lowerBound + 1) / 2) - 1 + lowerBound;
var end = (upperBound - lowerBound + 1) - 1 + lowerBound; var end = (upperBound - lowerBound + 1) - 1 + lowerBound;
@ -736,7 +736,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
/// <param name="sortedIndices">Indices of <paramref name="values"/></param> /// <param name="sortedIndices">Indices of <paramref name="values"/></param>
/// <param name="values">Target <see cref="Vector{T}"/></param> /// <param name="values">Target <see cref="Vector{T}"/></param>
private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector<Complex> values) static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector<Complex> values)
{ {
while (start >= 0) while (start >= 0)
{ {
@ -752,7 +752,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="values">Target <see cref="Vector{T}"/></param> /// <param name="values">Target <see cref="Vector{T}"/></param>
/// <param name="begin">Root position</param> /// <param name="begin">Root position</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void SiftDoubleIndices(int[] sortedIndices, Vector<Complex> values, int begin, int count) static void SiftDoubleIndices(int[] sortedIndices, Vector<Complex> values, int begin, int count)
{ {
var root = begin; var root = begin;
@ -788,7 +788,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </summary> /// </summary>
/// <param name="values">Array of values to sort</param> /// <param name="values">Array of values to sort</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void HeapSortIntegers(int[] values, int count) static void HeapSortIntegers(int[] values, int count)
{ {
var start = (count / 2) - 1; var start = (count / 2) - 1;
var end = count - 1; var end = count - 1;
@ -809,7 +809,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void BuildHeap(int[] values, int start, int count) static void BuildHeap(int[] values, int start, int count)
{ {
while (start >= 0) while (start >= 0)
{ {
@ -824,7 +824,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="values">Target value array</param> /// <param name="values">Target value array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void Sift(int[] values, int start, int count) static void Sift(int[] values, int start, int count)
{ {
var root = start; var root = start;
@ -854,7 +854,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="first">First value to exchange</param> /// <param name="first">First value to exchange</param>
/// <param name="second">Second value to exchange</param> /// <param name="second">Second value to exchange</param>
private static void Exchange(int[] values, int first, int second) static void Exchange(int[] values, int first, int second)
{ {
var t = values[first]; var t = values[first];
values[first] = values[second]; values[first] = values[second];

8
src/Numerics/LinearAlgebra/Complex/Solvers/MILU0Preconditioner.cs

@ -49,13 +49,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
// The diagonal (stored in alu(0:n-1) ) is inverted. Each i-th row of the matrix // The diagonal (stored in alu(0:n-1) ) is inverted. Each i-th row of the matrix
// contains the i-th row of L (excluding the diagonal entry = 1) followed by // contains the i-th row of L (excluding the diagonal entry = 1) followed by
// the i-th row of U. // the i-th row of U.
private Complex[] _alu; Complex[] _alu;
// The row pointers (stored in jlu(0:n) ) and column indices to off-diagonal elements. // The row pointers (stored in jlu(0:n) ) and column indices to off-diagonal elements.
private int[] _jlu; int[] _jlu;
// Pointer to the diagonal elements in MSR storage (for faster LU solving). // Pointer to the diagonal elements in MSR storage (for faster LU solving).
private int[] _diag; int[] _diag;
/// <param name="modified">Use modified or standard ILU(0)</param> /// <param name="modified">Use modified or standard ILU(0)</param>
public MILU0Preconditioner(bool modified = true) public MILU0Preconditioner(bool modified = true)
@ -165,7 +165,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="ju">Pointer to diagonal elements (output).</param> /// <param name="ju">Pointer to diagonal elements (output).</param>
/// <param name="modified">True if the modified/MILU algorithm should be used (recommended)</param> /// <param name="modified">True if the modified/MILU algorithm should be used (recommended)</param>
/// <returns>Returns 0 on success or k > 0 if a zero pivot was encountered at step k.</returns> /// <returns>Returns 0 on success or k > 0 if a zero pivot was encountered at step k.</returns>
private int Compute(int n, Complex[] a, int[] ja, int[] ia, Complex[] alu, int[] jlu, int[] ju, bool modified) int Compute(int n, Complex[] a, int[] ja, int[] ia, Complex[] alu, int[] jlu, int[] ju, bool modified)
{ {
var iw = new int[n]; var iw = new int[n];
int i; int i;

8
src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs

@ -412,7 +412,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// Puts the lower triangle of this matrix into the result matrix. /// Puts the lower triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void LowerTriangleImpl(Matrix<Complex> result) void LowerTriangleImpl(Matrix<Complex> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;
@ -477,7 +477,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// Puts the upper triangle of this matrix into the result matrix. /// Puts the upper triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void UpperTriangleImpl(Matrix<Complex> result) void UpperTriangleImpl(Matrix<Complex> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;
@ -543,7 +543,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// Puts the strictly lower triangle of this matrix into the result matrix. /// Puts the strictly lower triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void StrictlyLowerTriangleImpl(Matrix<Complex> result) void StrictlyLowerTriangleImpl(Matrix<Complex> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;
@ -609,7 +609,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// Puts the strictly upper triangle of this matrix into the result matrix. /// Puts the strictly upper triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void StrictlyUpperTriangleImpl(Matrix<Complex> result) void StrictlyUpperTriangleImpl(Matrix<Complex> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;

2
src/Numerics/LinearAlgebra/Complex/Vector.cs

@ -251,7 +251,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
protected override void DoPointwiseAbs(Vector<Complex> result) protected override void DoPointwiseAbs(Vector<Complex> result)
{ {
Map(x => (Complex)Complex.Abs(x), result, Zeros.AllowSkip); Map(x => Complex.Abs(x), result, Zeros.AllowSkip);
} }
protected override void DoPointwiseAcos(Vector<Complex> result) protected override void DoPointwiseAcos(Vector<Complex> result)
{ {

4
src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs

@ -54,14 +54,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// </summary> /// </summary>
/// <remarks>Using this instead of the RowCount property to speed up calculating /// <remarks>Using this instead of the RowCount property to speed up calculating
/// a matrix index in the data array.</remarks> /// a matrix index in the data array.</remarks>
private readonly int _rowCount; readonly int _rowCount;
/// <summary> /// <summary>
/// Number of columns. /// Number of columns.
/// </summary> /// </summary>
/// <remarks>Using this instead of the ColumnCount property to speed up calculating /// <remarks>Using this instead of the ColumnCount property to speed up calculating
/// a matrix index in the data array.</remarks> /// a matrix index in the data array.</remarks>
private readonly int _columnCount; readonly int _columnCount;
/// <summary> /// <summary>
/// Gets the matrix's data. /// Gets the matrix's data.

2
src/Numerics/LinearAlgebra/Complex32/Factorization/DenseGramSchmidt.cs

@ -78,7 +78,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
/// <param name="rowsQ">Number of rows in <see cref="Matrix{T}"/> Q.</param> /// <param name="rowsQ">Number of rows in <see cref="Matrix{T}"/> Q.</param>
/// <param name="columnsQ">Number of columns in <see cref="Matrix{T}"/> Q.</param> /// <param name="columnsQ">Number of columns in <see cref="Matrix{T}"/> Q.</param>
/// <param name="r">On exit is filled by <see cref="Matrix{T}"/> R.</param> /// <param name="r">On exit is filled by <see cref="Matrix{T}"/> R.</param>
private static void Factorize(Complex32[] q, int rowsQ, int columnsQ, Complex32[] r) static void Factorize(Complex32[] q, int rowsQ, int columnsQ, Complex32[] r)
{ {
for (var k = 0; k < columnsQ; k++) for (var k = 0; k < columnsQ; k++)
{ {

14
src/Numerics/LinearAlgebra/Complex32/Solvers/ILUTPPreconditioner.cs

@ -720,7 +720,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="upperBound">The stopping index.</param> /// <param name="upperBound">The stopping index.</param>
/// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param> /// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param>
/// <param name="values">The <see cref="Vector"/> that contains the values that need to be sorted.</param> /// <param name="values">The <see cref="Vector"/> that contains the values that need to be sorted.</param>
private static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector<Complex32> values) static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector<Complex32> values)
{ {
var start = ((upperBound - lowerBound + 1) / 2) - 1 + lowerBound; var start = ((upperBound - lowerBound + 1) / 2) - 1 + lowerBound;
var end = (upperBound - lowerBound + 1) - 1 + lowerBound; var end = (upperBound - lowerBound + 1) - 1 + lowerBound;
@ -742,7 +742,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
/// <param name="sortedIndices">Indices of <paramref name="values"/></param> /// <param name="sortedIndices">Indices of <paramref name="values"/></param>
/// <param name="values">Target <see cref="Vector"/></param> /// <param name="values">Target <see cref="Vector"/></param>
private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector<Complex32> values) static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector<Complex32> values)
{ {
while (start >= 0) while (start >= 0)
{ {
@ -758,7 +758,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="values">Target <see cref="Vector"/></param> /// <param name="values">Target <see cref="Vector"/></param>
/// <param name="begin">Root position</param> /// <param name="begin">Root position</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void SiftDoubleIndices(int[] sortedIndices, Vector<Complex32> values, int begin, int count) static void SiftDoubleIndices(int[] sortedIndices, Vector<Complex32> values, int begin, int count)
{ {
var root = begin; var root = begin;
@ -794,7 +794,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </summary> /// </summary>
/// <param name="values">Array of values to sort</param> /// <param name="values">Array of values to sort</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void HeapSortIntegers(int[] values, int count) static void HeapSortIntegers(int[] values, int count)
{ {
var start = (count / 2) - 1; var start = (count / 2) - 1;
var end = count - 1; var end = count - 1;
@ -815,7 +815,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void BuildHeap(int[] values, int start, int count) static void BuildHeap(int[] values, int start, int count)
{ {
while (start >= 0) while (start >= 0)
{ {
@ -830,7 +830,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="values">Target value array</param> /// <param name="values">Target value array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void Sift(int[] values, int start, int count) static void Sift(int[] values, int start, int count)
{ {
var root = start; var root = start;
@ -860,7 +860,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="first">First value to exchange</param> /// <param name="first">First value to exchange</param>
/// <param name="second">Second value to exchange</param> /// <param name="second">Second value to exchange</param>
private static void Exchange(int[] values, int first, int second) static void Exchange(int[] values, int first, int second)
{ {
var t = values[first]; var t = values[first];
values[first] = values[second]; values[first] = values[second];

8
src/Numerics/LinearAlgebra/Complex32/Solvers/MILU0Preconditioner.cs

@ -49,13 +49,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
// The diagonal (stored in alu(0:n-1) ) is inverted. Each i-th row of the matrix // The diagonal (stored in alu(0:n-1) ) is inverted. Each i-th row of the matrix
// contains the i-th row of L (excluding the diagonal entry = 1) followed by // contains the i-th row of L (excluding the diagonal entry = 1) followed by
// the i-th row of U. // the i-th row of U.
private Complex32[] _alu; Complex32[] _alu;
// The row pointers (stored in jlu(0:n) ) and column indices to off-diagonal elements. // The row pointers (stored in jlu(0:n) ) and column indices to off-diagonal elements.
private int[] _jlu; int[] _jlu;
// Pointer to the diagonal elements in MSR storage (for faster LU solving). // Pointer to the diagonal elements in MSR storage (for faster LU solving).
private int[] _diag; int[] _diag;
/// <param name="modified">Use modified or standard ILU(0)</param> /// <param name="modified">Use modified or standard ILU(0)</param>
public MILU0Preconditioner(bool modified = true) public MILU0Preconditioner(bool modified = true)
@ -165,7 +165,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="ju">Pointer to diagonal elements (output).</param> /// <param name="ju">Pointer to diagonal elements (output).</param>
/// <param name="modified">True if the modified/MILU algorithm should be used (recommended)</param> /// <param name="modified">True if the modified/MILU algorithm should be used (recommended)</param>
/// <returns>Returns 0 on success or k > 0 if a zero pivot was encountered at step k.</returns> /// <returns>Returns 0 on success or k > 0 if a zero pivot was encountered at step k.</returns>
private int Compute(int n, Complex32[] a, int[] ja, int[] ia, Complex32[] alu, int[] jlu, int[] ju, bool modified) int Compute(int n, Complex32[] a, int[] ja, int[] ia, Complex32[] alu, int[] jlu, int[] ju, bool modified)
{ {
var iw = new int[n]; var iw = new int[n];
int i; int i;

8
src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs

@ -412,7 +412,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// Puts the lower triangle of this matrix into the result matrix. /// Puts the lower triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void LowerTriangleImpl(Matrix<Complex32> result) void LowerTriangleImpl(Matrix<Complex32> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;
@ -477,7 +477,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// Puts the upper triangle of this matrix into the result matrix. /// Puts the upper triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void UpperTriangleImpl(Matrix<Complex32> result) void UpperTriangleImpl(Matrix<Complex32> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;
@ -543,7 +543,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// Puts the strictly lower triangle of this matrix into the result matrix. /// Puts the strictly lower triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void StrictlyLowerTriangleImpl(Matrix<Complex32> result) void StrictlyLowerTriangleImpl(Matrix<Complex32> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;
@ -609,7 +609,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// Puts the strictly upper triangle of this matrix into the result matrix. /// Puts the strictly upper triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void StrictlyUpperTriangleImpl(Matrix<Complex32> result) void StrictlyUpperTriangleImpl(Matrix<Complex32> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;

2
src/Numerics/LinearAlgebra/Double/Factorization/DenseGramSchmidt.cs

@ -76,7 +76,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="rowsQ">Number of rows in <see cref="Matrix{T}"/> Q.</param> /// <param name="rowsQ">Number of rows in <see cref="Matrix{T}"/> Q.</param>
/// <param name="columnsQ">Number of columns in <see cref="Matrix{T}"/> Q.</param> /// <param name="columnsQ">Number of columns in <see cref="Matrix{T}"/> Q.</param>
/// <param name="r">On exit is filled by <see cref="Matrix{T}"/> R.</param> /// <param name="r">On exit is filled by <see cref="Matrix{T}"/> R.</param>
private static void Factorize(double[] q, int rowsQ, int columnsQ, double[] r) static void Factorize(double[] q, int rowsQ, int columnsQ, double[] r)
{ {
for (var k = 0; k < columnsQ; k++) for (var k = 0; k < columnsQ; k++)
{ {

2
src/Numerics/LinearAlgebra/Double/Matrix.cs

@ -469,7 +469,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
protected override void DoPointwiseSign(Matrix<double> result) protected override void DoPointwiseSign(Matrix<double> result)
{ {
Map(x => (double)Math.Sign(x), result, Zeros.AllowSkip); Map(x => Math.Sign(x), result, Zeros.AllowSkip);
} }
protected override void DoPointwiseSin(Matrix<double> result) protected override void DoPointwiseSin(Matrix<double> result)
{ {

14
src/Numerics/LinearAlgebra/Double/Solvers/ILUTPPreconditioner.cs

@ -718,7 +718,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="upperBound">The stopping index.</param> /// <param name="upperBound">The stopping index.</param>
/// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param> /// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param>
/// <param name="values">The <see cref="Vector"/> that contains the values that need to be sorted.</param> /// <param name="values">The <see cref="Vector"/> that contains the values that need to be sorted.</param>
private static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector<double> values) static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector<double> values)
{ {
var start = ((upperBound - lowerBound + 1) / 2) - 1 + lowerBound; var start = ((upperBound - lowerBound + 1) / 2) - 1 + lowerBound;
var end = (upperBound - lowerBound + 1) - 1 + lowerBound; var end = (upperBound - lowerBound + 1) - 1 + lowerBound;
@ -740,7 +740,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
/// <param name="sortedIndices">Indices of <paramref name="values"/></param> /// <param name="sortedIndices">Indices of <paramref name="values"/></param>
/// <param name="values">Target <see cref="Vector"/></param> /// <param name="values">Target <see cref="Vector"/></param>
private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector<double> values) static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector<double> values)
{ {
while (start >= 0) while (start >= 0)
{ {
@ -756,7 +756,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="values">Target <see cref="Vector"/></param> /// <param name="values">Target <see cref="Vector"/></param>
/// <param name="begin">Root position</param> /// <param name="begin">Root position</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void SiftDoubleIndices(int[] sortedIndices, Vector<double> values, int begin, int count) static void SiftDoubleIndices(int[] sortedIndices, Vector<double> values, int begin, int count)
{ {
var root = begin; var root = begin;
@ -792,7 +792,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </summary> /// </summary>
/// <param name="values">Array of values to sort</param> /// <param name="values">Array of values to sort</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void HeapSortIntegers(int[] values, int count) static void HeapSortIntegers(int[] values, int count)
{ {
var start = (count / 2) - 1; var start = (count / 2) - 1;
var end = count - 1; var end = count - 1;
@ -813,7 +813,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void BuildHeap(int[] values, int start, int count) static void BuildHeap(int[] values, int start, int count)
{ {
while (start >= 0) while (start >= 0)
{ {
@ -828,7 +828,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="values">Target value array</param> /// <param name="values">Target value array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void Sift(int[] values, int start, int count) static void Sift(int[] values, int start, int count)
{ {
var root = start; var root = start;
@ -858,7 +858,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="first">First value to exchange</param> /// <param name="first">First value to exchange</param>
/// <param name="second">Second value to exchange</param> /// <param name="second">Second value to exchange</param>
private static void Exchange(int[] values, int first, int second) static void Exchange(int[] values, int first, int second)
{ {
var t = values[first]; var t = values[first];
values[first] = values[second]; values[first] = values[second];

8
src/Numerics/LinearAlgebra/Double/Solvers/MILU0Preconditioner.cs

@ -47,13 +47,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
// The diagonal (stored in alu(0:n-1) ) is inverted. Each i-th row of the matrix // The diagonal (stored in alu(0:n-1) ) is inverted. Each i-th row of the matrix
// contains the i-th row of L (excluding the diagonal entry = 1) followed by // contains the i-th row of L (excluding the diagonal entry = 1) followed by
// the i-th row of U. // the i-th row of U.
private double[] _alu; double[] _alu;
// The row pointers (stored in jlu(0:n) ) and column indices to off-diagonal elements. // The row pointers (stored in jlu(0:n) ) and column indices to off-diagonal elements.
private int[] _jlu; int[] _jlu;
// Pointer to the diagonal elements in MSR storage (for faster LU solving). // Pointer to the diagonal elements in MSR storage (for faster LU solving).
private int[] _diag; int[] _diag;
/// <param name="modified">Use modified or standard ILU(0)</param> /// <param name="modified">Use modified or standard ILU(0)</param>
public MILU0Preconditioner(bool modified = true) public MILU0Preconditioner(bool modified = true)
@ -163,7 +163,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="ju">Pointer to diagonal elements (output).</param> /// <param name="ju">Pointer to diagonal elements (output).</param>
/// <param name="modified">True if the modified/MILU algorithm should be used (recommended)</param> /// <param name="modified">True if the modified/MILU algorithm should be used (recommended)</param>
/// <returns>Returns 0 on success or k > 0 if a zero pivot was encountered at step k.</returns> /// <returns>Returns 0 on success or k > 0 if a zero pivot was encountered at step k.</returns>
private int Compute(int n, double[] a, int[] ja, int[] ia, double[] alu, int[] jlu, int[] ju, bool modified) int Compute(int n, double[] a, int[] ja, int[] ia, double[] alu, int[] jlu, int[] ju, bool modified)
{ {
var iw = new int[n]; var iw = new int[n];
int i; int i;

8
src/Numerics/LinearAlgebra/Double/SparseMatrix.cs

@ -410,7 +410,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Puts the lower triangle of this matrix into the result matrix. /// Puts the lower triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void LowerTriangleImpl(Matrix<double> result) void LowerTriangleImpl(Matrix<double> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;
@ -475,7 +475,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Puts the upper triangle of this matrix into the result matrix. /// Puts the upper triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void UpperTriangleImpl(Matrix<double> result) void UpperTriangleImpl(Matrix<double> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;
@ -541,7 +541,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Puts the strictly lower triangle of this matrix into the result matrix. /// Puts the strictly lower triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void StrictlyLowerTriangleImpl(Matrix<double> result) void StrictlyLowerTriangleImpl(Matrix<double> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;
@ -607,7 +607,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Puts the strictly upper triangle of this matrix into the result matrix. /// Puts the strictly upper triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void StrictlyUpperTriangleImpl(Matrix<double> result) void StrictlyUpperTriangleImpl(Matrix<double> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;

2
src/Numerics/LinearAlgebra/Double/Vector.cs

@ -302,7 +302,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
protected override void DoPointwiseSign(Vector<double> result) protected override void DoPointwiseSign(Vector<double> result)
{ {
Map(x => (double)Math.Sign(x), result, Zeros.AllowSkip); Map(x => Math.Sign(x), result, Zeros.AllowSkip);
} }
protected override void DoPointwiseSin(Vector<double> result) protected override void DoPointwiseSin(Vector<double> result)
{ {

2
src/Numerics/LinearAlgebra/Factorization/Cholesky.cs

@ -52,7 +52,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
/// <summary> /// <summary>
/// Gets the lower triangular form of the Cholesky matrix. /// Gets the lower triangular form of the Cholesky matrix.
/// </summary> /// </summary>
public Matrix<T> Factor { get; private set; } public Matrix<T> Factor { get; }
/// <summary> /// <summary>
/// Gets the determinant of the matrix for which the Cholesky matrix was computed. /// Gets the determinant of the matrix for which the Cholesky matrix was computed.

8
src/Numerics/LinearAlgebra/Factorization/Evd.cs

@ -64,7 +64,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
/// <summary> /// <summary>
/// Gets or sets a value indicating whether matrix is symmetric or not /// Gets or sets a value indicating whether matrix is symmetric or not
/// </summary> /// </summary>
public bool IsSymmetric { get; private set; } public bool IsSymmetric { get; }
/// <summary> /// <summary>
/// Gets the absolute value of determinant of the square matrix for which the EVD was computed. /// Gets the absolute value of determinant of the square matrix for which the EVD was computed.
@ -86,17 +86,17 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
/// <summary> /// <summary>
/// Gets or sets the eigen values (λ) of matrix in ascending value. /// Gets or sets the eigen values (λ) of matrix in ascending value.
/// </summary> /// </summary>
public Vector<Complex> EigenValues { get; private set; } public Vector<Complex> EigenValues { get; }
/// <summary> /// <summary>
/// Gets or sets eigenvectors. /// Gets or sets eigenvectors.
/// </summary> /// </summary>
public Matrix<T> EigenVectors { get; private set; } public Matrix<T> EigenVectors { get; }
/// <summary> /// <summary>
/// Gets or sets the block diagonal eigenvalue matrix. /// Gets or sets the block diagonal eigenvalue matrix.
/// </summary> /// </summary>
public Matrix<T> D { get; private set; } public Matrix<T> D { get; }
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A EVD factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A EVD factorized.

2
src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs

@ -1045,7 +1045,7 @@ namespace MathNet.Numerics.LinearAlgebra
return result; return result;
} }
private static Matrix<T> IntPower(int exponent, Matrix<T> x, Matrix<T> y, Matrix<T> work) static Matrix<T> IntPower(int exponent, Matrix<T> x, Matrix<T> y, Matrix<T> work)
{ {
// We try to be smart about not allocating more matrices than needed // We try to be smart about not allocating more matrices than needed
// and to minimize the number of multiplications (not optimal on either though) // and to minimize the number of multiplications (not optimal on either though)

2
src/Numerics/LinearAlgebra/Single/Factorization/DenseGramSchmidt.cs

@ -76,7 +76,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
/// <param name="rowsQ">Number of rows in <see cref="Matrix{T}"/> Q.</param> /// <param name="rowsQ">Number of rows in <see cref="Matrix{T}"/> Q.</param>
/// <param name="columnsQ">Number of columns in <see cref="Matrix{T}"/> Q.</param> /// <param name="columnsQ">Number of columns in <see cref="Matrix{T}"/> Q.</param>
/// <param name="r">On exit is filled by <see cref="Matrix{T}"/> R.</param> /// <param name="r">On exit is filled by <see cref="Matrix{T}"/> R.</param>
private static void Factorize(float[] q, int rowsQ, int columnsQ, float[] r) static void Factorize(float[] q, int rowsQ, int columnsQ, float[] r)
{ {
for (var k = 0; k < columnsQ; k++) for (var k = 0; k < columnsQ; k++)
{ {

6
src/Numerics/LinearAlgebra/Single/Matrix.cs

@ -425,7 +425,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
protected override void DoPointwiseAbs(Matrix<float> result) protected override void DoPointwiseAbs(Matrix<float> result)
{ {
Map(x => (float)Math.Abs(x), result, Zeros.AllowSkip); Map(x => Math.Abs(x), result, Zeros.AllowSkip);
} }
protected override void DoPointwiseAcos(Matrix<float> result) protected override void DoPointwiseAcos(Matrix<float> result)
{ {
@ -441,7 +441,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
} }
protected override void DoPointwiseAtan2(Matrix<float> other, Matrix<float> result) protected override void DoPointwiseAtan2(Matrix<float> other, Matrix<float> result)
{ {
Map2((x, y) => (float)Math.Atan2((double)x, (double)y), other, result, Zeros.Include); Map2((x, y) => (float)Math.Atan2(x, y), other, result, Zeros.Include);
} }
protected override void DoPointwiseCeiling(Matrix<float> result) protected override void DoPointwiseCeiling(Matrix<float> result)
{ {
@ -469,7 +469,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
} }
protected override void DoPointwiseSign(Matrix<float> result) protected override void DoPointwiseSign(Matrix<float> result)
{ {
Map(x => (float)Math.Sign(x), result, Zeros.AllowSkip); Map(x => Math.Sign(x), result, Zeros.AllowSkip);
} }
protected override void DoPointwiseSin(Matrix<float> result) protected override void DoPointwiseSin(Matrix<float> result)
{ {

14
src/Numerics/LinearAlgebra/Single/Solvers/ILUTPPreconditioner.cs

@ -718,7 +718,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="upperBound">The stopping index.</param> /// <param name="upperBound">The stopping index.</param>
/// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param> /// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param>
/// <param name="values">The <see cref="Vector"/> that contains the values that need to be sorted.</param> /// <param name="values">The <see cref="Vector"/> that contains the values that need to be sorted.</param>
private static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector<float> values) static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector<float> values)
{ {
var start = ((upperBound - lowerBound + 1) / 2) - 1 + lowerBound; var start = ((upperBound - lowerBound + 1) / 2) - 1 + lowerBound;
var end = (upperBound - lowerBound + 1) - 1 + lowerBound; var end = (upperBound - lowerBound + 1) - 1 + lowerBound;
@ -740,7 +740,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
/// <param name="sortedIndices">Indices of <paramref name="values"/></param> /// <param name="sortedIndices">Indices of <paramref name="values"/></param>
/// <param name="values">Target <see cref="Vector"/></param> /// <param name="values">Target <see cref="Vector"/></param>
private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector<float> values) static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector<float> values)
{ {
while (start >= 0) while (start >= 0)
{ {
@ -756,7 +756,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="values">Target <see cref="Vector"/></param> /// <param name="values">Target <see cref="Vector"/></param>
/// <param name="begin">Root position</param> /// <param name="begin">Root position</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void SiftDoubleIndices(int[] sortedIndices, Vector<float> values, int begin, int count) static void SiftDoubleIndices(int[] sortedIndices, Vector<float> values, int begin, int count)
{ {
var root = begin; var root = begin;
@ -792,7 +792,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </summary> /// </summary>
/// <param name="values">Array of values to sort</param> /// <param name="values">Array of values to sort</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void HeapSortIntegers(int[] values, int count) static void HeapSortIntegers(int[] values, int count)
{ {
var start = (count / 2) - 1; var start = (count / 2) - 1;
var end = count - 1; var end = count - 1;
@ -813,7 +813,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void BuildHeap(int[] values, int start, int count) static void BuildHeap(int[] values, int start, int count)
{ {
while (start >= 0) while (start >= 0)
{ {
@ -828,7 +828,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="values">Target value array</param> /// <param name="values">Target value array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Length of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void Sift(int[] values, int start, int count) static void Sift(int[] values, int start, int count)
{ {
var root = start; var root = start;
@ -858,7 +858,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="first">First value to exchange</param> /// <param name="first">First value to exchange</param>
/// <param name="second">Second value to exchange</param> /// <param name="second">Second value to exchange</param>
private static void Exchange(int[] values, int first, int second) static void Exchange(int[] values, int first, int second)
{ {
var t = values[first]; var t = values[first];
values[first] = values[second]; values[first] = values[second];

8
src/Numerics/LinearAlgebra/Single/Solvers/MILU0Preconditioner.cs

@ -47,13 +47,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
// The diagonal (stored in alu(0:n-1) ) is inverted. Each i-th row of the matrix // The diagonal (stored in alu(0:n-1) ) is inverted. Each i-th row of the matrix
// contains the i-th row of L (excluding the diagonal entry = 1) followed by // contains the i-th row of L (excluding the diagonal entry = 1) followed by
// the i-th row of U. // the i-th row of U.
private float[] _alu; float[] _alu;
// The row pointers (stored in jlu(0:n) ) and column indices to off-diagonal elements. // The row pointers (stored in jlu(0:n) ) and column indices to off-diagonal elements.
private int[] _jlu; int[] _jlu;
// Pointer to the diagonal elements in MSR storage (for faster LU solving). // Pointer to the diagonal elements in MSR storage (for faster LU solving).
private int[] _diag; int[] _diag;
/// <param name="modified">Use modified or standard ILU(0)</param> /// <param name="modified">Use modified or standard ILU(0)</param>
public MILU0Preconditioner(bool modified = true) public MILU0Preconditioner(bool modified = true)
@ -163,7 +163,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="ju">Pointer to diagonal elements (output).</param> /// <param name="ju">Pointer to diagonal elements (output).</param>
/// <param name="modified">True if the modified/MILU algorithm should be used (recommended)</param> /// <param name="modified">True if the modified/MILU algorithm should be used (recommended)</param>
/// <returns>Returns 0 on success or k > 0 if a zero pivot was encountered at step k.</returns> /// <returns>Returns 0 on success or k > 0 if a zero pivot was encountered at step k.</returns>
private int Compute(int n, float[] a, int[] ja, int[] ia, float[] alu, int[] jlu, int[] ju, bool modified) int Compute(int n, float[] a, int[] ja, int[] ia, float[] alu, int[] jlu, int[] ju, bool modified)
{ {
var iw = new int[n]; var iw = new int[n];
int i; int i;

8
src/Numerics/LinearAlgebra/Single/SparseMatrix.cs

@ -411,7 +411,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// Puts the lower triangle of this matrix into the result matrix. /// Puts the lower triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void LowerTriangleImpl(Matrix<float> result) void LowerTriangleImpl(Matrix<float> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;
@ -476,7 +476,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// Puts the upper triangle of this matrix into the result matrix. /// Puts the upper triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void UpperTriangleImpl(Matrix<float> result) void UpperTriangleImpl(Matrix<float> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;
@ -542,7 +542,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// Puts the strictly lower triangle of this matrix into the result matrix. /// Puts the strictly lower triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void StrictlyLowerTriangleImpl(Matrix<float> result) void StrictlyLowerTriangleImpl(Matrix<float> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;
@ -608,7 +608,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// Puts the strictly upper triangle of this matrix into the result matrix. /// Puts the strictly upper triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void StrictlyUpperTriangleImpl(Matrix<float> result) void StrictlyUpperTriangleImpl(Matrix<float> result)
{ {
var rowPointers = _storage.RowPointers; var rowPointers = _storage.RowPointers;
var columnIndices = _storage.ColumnIndices; var columnIndices = _storage.ColumnIndices;

8
src/Numerics/LinearAlgebra/Single/Vector.cs

@ -254,7 +254,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
protected override void DoPointwiseAbs(Vector<float> result) protected override void DoPointwiseAbs(Vector<float> result)
{ {
Map(x => (float)Math.Abs(x), result, Zeros.AllowSkip); Map(x => Math.Abs(x), result, Zeros.AllowSkip);
} }
protected override void DoPointwiseAcos(Vector<float> result) protected override void DoPointwiseAcos(Vector<float> result)
{ {
@ -270,11 +270,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single
} }
protected override void DoPointwiseAtan2(Vector<float> other, Vector<float> result) protected override void DoPointwiseAtan2(Vector<float> other, Vector<float> result)
{ {
Map2((x, y) => (float)Math.Atan2((double)x, (double)y), other, result, Zeros.Include); Map2((x, y) => (float)Math.Atan2(x, y), other, result, Zeros.Include);
} }
protected override void DoPointwiseAtan2(float scalar, Vector<float> result) protected override void DoPointwiseAtan2(float scalar, Vector<float> result)
{ {
Map(x => (float)Math.Atan2((double)x, (double)scalar), result, Zeros.Include); Map(x => (float)Math.Atan2(x, scalar), result, Zeros.Include);
} }
protected override void DoPointwiseCeiling(Vector<float> result) protected override void DoPointwiseCeiling(Vector<float> result)
{ {
@ -302,7 +302,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
} }
protected override void DoPointwiseSign(Vector<float> result) protected override void DoPointwiseSign(Vector<float> result)
{ {
Map(x => (float)Math.Sign(x), result, Zeros.AllowSkip); Map(x => Math.Sign(x), result, Zeros.AllowSkip);
} }
protected override void DoPointwiseSin(Vector<float> result) protected override void DoPointwiseSin(Vector<float> result)
{ {

3
src/Numerics/Optimization/BfgsBMinimizer.cs

@ -147,7 +147,6 @@ namespace MathNet.Numerics.Optimization
if (currentExitCondition != ExitCondition.None) if (currentExitCondition != ExitCondition.None)
return new MinimizationResult(candidatePoint, 0, currentExitCondition); return new MinimizationResult(candidatePoint, 0, currentExitCondition);
var gradient = candidatePoint.Gradient;
var step = candidatePoint.Point - initialGuess; var step = candidatePoint.Point - initialGuess;
// Subsequent steps // Subsequent steps
@ -175,8 +174,6 @@ namespace MathNet.Numerics.Optimization
double sy = step * y; double sy = step * y;
if (sy > 0.0) // only do update if it will create a positive definite matrix if (sy > 0.0) // only do update if it will create a positive definite matrix
{ {
double sts = step * step;
var Hs = pseudoHessian * step; var Hs = pseudoHessian * step;
var sHs = step * pseudoHessian * step; var sHs = step * pseudoHessian * step;
pseudoHessian = pseudoHessian + y.OuterProduct(y) * (1.0 / sy) - Hs.OuterProduct(Hs) * (1.0 / sHs); pseudoHessian = pseudoHessian + y.OuterProduct(y) * (1.0 / sy) - Hs.OuterProduct(Hs) * (1.0 / sHs);

1
src/Numerics/Optimization/BfgsMinimizer.cs

@ -96,7 +96,6 @@ namespace MathNet.Numerics.Optimization
var candidate = lineSearchResult.FunctionInfoAtMinimum; var candidate = lineSearchResult.FunctionInfoAtMinimum;
ValidateGradientAndObjective(candidate); ValidateGradientAndObjective(candidate);
var gradient = candidate.Gradient;
var step = candidate.Point - initialGuess; var step = candidate.Point - initialGuess;
// Subsequent steps // Subsequent steps

4
src/Numerics/Optimization/BfgsMinimizerBase.cs

@ -49,9 +49,7 @@ namespace MathNet.Numerics.Optimization
int iterations; int iterations;
for (iterations = 1; iterations < MaximumIterations; ++iterations) for (iterations = 1; iterations < MaximumIterations; ++iterations)
{ {
double startingStepSize; lineSearchDirection = CalculateSearchDirection(ref inversePseudoHessian, out var maxLineSearchStep, out var startingStepSize, previousPoint, candidate, step);
double maxLineSearchStep;
lineSearchDirection = CalculateSearchDirection(ref inversePseudoHessian, out maxLineSearchStep, out startingStepSize, previousPoint, candidate, step);
try try
{ {

4
src/Numerics/Optimization/BfgsSolver.cs

@ -41,8 +41,8 @@ namespace MathNet.Numerics.Optimization
/// </summary> /// </summary>
public static class BfgsSolver public static class BfgsSolver
{ {
private const double GradientTolerance = 1e-5; const double GradientTolerance = 1e-5;
private const int MaxIterations = 100000; const int MaxIterations = 100000;
/// <summary> /// <summary>
/// Finds a minimum of a function by the BFGS quasi-Newton method /// Finds a minimum of a function by the BFGS quasi-Newton method

6
src/Numerics/Optimization/Exceptions.cs

@ -48,7 +48,7 @@ namespace MathNet.Numerics.Optimization
public class EvaluationException : OptimizationException public class EvaluationException : OptimizationException
{ {
public IObjectiveFunctionEvaluation ObjectiveFunction { get; private set; } public IObjectiveFunctionEvaluation ObjectiveFunction { get; }
public EvaluationException(string message, IObjectiveFunctionEvaluation eval) public EvaluationException(string message, IObjectiveFunctionEvaluation eval)
: base(message) : base(message)
@ -69,8 +69,8 @@ namespace MathNet.Numerics.Optimization
public InnerOptimizationException(string message) public InnerOptimizationException(string message)
: base(message) { } : base(message) { }
public InnerOptimizationException(string message, Exception inner_exception) public InnerOptimizationException(string message, Exception innerException)
: base(message, inner_exception) { } : base(message, innerException) { }
} }
public class IncompatibleObjectiveException : OptimizationException public class IncompatibleObjectiveException : OptimizationException

6
src/Numerics/Optimization/GoldenSectionMinimizer.cs

@ -69,8 +69,8 @@ namespace MathNet.Numerics.Optimization
ValueChecker(middle.Value, middlePointX); ValueChecker(middle.Value, middlePointX);
ValueChecker(upper.Value, upperBound); ValueChecker(upper.Value, upperBound);
int expansion_steps = 0; int expansionSteps = 0;
while ((expansion_steps < maxExpansionSteps) && (upper.Value < middle.Value || lower.Value < middle.Value)) while ((expansionSteps < maxExpansionSteps) && (upper.Value < middle.Value || lower.Value < middle.Value))
{ {
if (lower.Value < middle.Value) if (lower.Value < middle.Value)
{ {
@ -87,7 +87,7 @@ namespace MathNet.Numerics.Optimization
middlePointX = lowerBound + (upperBound - lowerBound)/(1 + Constants.GoldenRatio); middlePointX = lowerBound + (upperBound - lowerBound)/(1 + Constants.GoldenRatio);
middle = objective.Evaluate(middlePointX); middle = objective.Evaluate(middlePointX);
expansion_steps += 1; expansionSteps += 1;
} }
if (upper.Value < middle.Value || lower.Value < middle.Value) if (upper.Value < middle.Value || lower.Value < middle.Value)

36
src/Numerics/Optimization/LevenbergMarquardtMinimizer.cs

@ -28,16 +28,16 @@ namespace MathNet.Numerics.Optimization
double[] lowerBound = null, double[] upperBound = null, double[] scales = null, bool[] isFixed = null) double[] lowerBound = null, double[] upperBound = null, double[] scales = null, bool[] isFixed = null)
{ {
if (objective == null) if (objective == null)
throw new ArgumentNullException("objective"); throw new ArgumentNullException(nameof(objective));
if (initialGuess == null) if (initialGuess == null)
throw new ArgumentNullException("initialGuess"); throw new ArgumentNullException(nameof(initialGuess));
var lb = (lowerBound == null) ? null : CreateVector.Dense<double>(lowerBound); var lb = (lowerBound == null) ? null : CreateVector.Dense(lowerBound);
var ub = (upperBound == null) ? null : CreateVector.Dense<double>(upperBound); var ub = (upperBound == null) ? null : CreateVector.Dense(upperBound);
var sc = (scales == null) ? null : CreateVector.Dense<double>(scales); var sc = (scales == null) ? null : CreateVector.Dense(scales);
var fx = (isFixed == null) ? null : isFixed.ToList(); var fx = isFixed?.ToList();
return Minimum(objective, CreateVector.DenseOfArray<double>(initialGuess), lb, ub, sc, fx, InitialMu, GradientTolerance, StepTolerance, FunctionTolerance, MaximumIterations); return Minimum(objective, CreateVector.DenseOfArray(initialGuess), lb, ub, sc, fx, InitialMu, GradientTolerance, StepTolerance, FunctionTolerance, MaximumIterations);
} }
/// <summary> /// <summary>
@ -45,7 +45,7 @@ namespace MathNet.Numerics.Optimization
/// </summary> /// </summary>
/// <param name="objective">The objective function, including model, observations, and parameter bounds.</param> /// <param name="objective">The objective function, including model, observations, and parameter bounds.</param>
/// <param name="initialGuess">The initial guess values.</param> /// <param name="initialGuess">The initial guess values.</param>
/// <param name="initialMu">The initial damping parameter of mu.</param> /// <param name="initialMu">The initial damping parameter of mu.</param>
/// <param name="gradientTolerance">The stopping threshold for infinity norm of the gradient vector.</param> /// <param name="gradientTolerance">The stopping threshold for infinity norm of the gradient vector.</param>
/// <param name="stepTolerance">The stopping threshold for L2 norm of the change of parameters.</param> /// <param name="stepTolerance">The stopping threshold for L2 norm of the change of parameters.</param>
/// <param name="functionTolerance">The stopping threshold for L2 norm of the residuals.</param> /// <param name="functionTolerance">The stopping threshold for L2 norm of the residuals.</param>
@ -70,12 +70,12 @@ namespace MathNet.Numerics.Optimization
// Residuals, R = L(y - f(x; p)) // Residuals, R = L(y - f(x; p))
// Residual sum of squares, RSS = ||R||^2 = R.DotProduct(R) // Residual sum of squares, RSS = ||R||^2 = R.DotProduct(R)
// Jacobian J = df(x; p)/dp // Jacobian J = df(x; p)/dp
// Gradient g = -J'W(y − f(x; p)) = -J'LR // Gradient g = -J'W(y − f(x; p)) = -J'LR
// Approximated Hessian H = J'WJ // Approximated Hessian H = J'WJ
// //
// The Levenberg-Marquardt algorithm is summarized as follows: // The Levenberg-Marquardt algorithm is summarized as follows:
// initially let μ = τ * max(diag(H)). // initially let μ = τ * max(diag(H)).
// repeat // repeat
// solve linear equations: (H + μI)ΔP = -g // solve linear equations: (H + μI)ΔP = -g
// let ρ = (||R||^2 - ||Rnew||^2) / (Δp'(μΔp - g)). // let ρ = (||R||^2 - ||Rnew||^2) / (Δp'(μΔp - g)).
// if ρ > ε, P = P + ΔP; μ = μ * max(1/3, 1 - (2ρ - 1)^3); ν = 2; // if ρ > ε, P = P + ΔP; μ = μ * max(1/3, 1 - (2ρ - 1)^3); ν = 2;
@ -91,17 +91,17 @@ namespace MathNet.Numerics.Optimization
// Availble Online from: http://people.duke.edu/~hpgavin/ce281/lm.pdf // Availble Online from: http://people.duke.edu/~hpgavin/ce281/lm.pdf
if (objective == null) if (objective == null)
throw new ArgumentNullException("objective"); throw new ArgumentNullException(nameof(objective));
ValidateBounds(initialGuess, lowerBound, upperBound, scales); ValidateBounds(initialGuess, lowerBound, upperBound, scales);
objective.SetParameters(initialGuess, isFixed); objective.SetParameters(initialGuess, isFixed);
ExitCondition exitCondition = ExitCondition.None; ExitCondition exitCondition = ExitCondition.None;
// First, calculate function values and setup variables // First, calculate function values and setup variables
var P = ProjectToInternalParameters(initialGuess); // current internal parameters var P = ProjectToInternalParameters(initialGuess); // current internal parameters
var Pstep = Vector<double>.Build.Dense(P.Count); // the change of parameters var Pstep = Vector<double>.Build.Dense(P.Count); // the change of parameters
var RSS = EvaluateFunction(objective, P); // Residual Sum of Squares = R'R var RSS = EvaluateFunction(objective, P); // Residual Sum of Squares = R'R
if (maximumIterations < 0) if (maximumIterations < 0)
@ -116,7 +116,7 @@ namespace MathNet.Numerics.Optimization
return new NonlinearMinimizationResult(objective, -1, exitCondition); return new NonlinearMinimizationResult(objective, -1, exitCondition);
} }
// When only function evaluation is needed, set maximumIterations to zero, // When only function evaluation is needed, set maximumIterations to zero,
if (maximumIterations == 0) if (maximumIterations == 0)
{ {
exitCondition = ExitCondition.ManuallyStopped; exitCondition = ExitCondition.ManuallyStopped;
@ -145,7 +145,7 @@ namespace MathNet.Numerics.Optimization
return new NonlinearMinimizationResult(objective, -1, exitCondition); return new NonlinearMinimizationResult(objective, -1, exitCondition);
} }
double mu = initialMu * diagonalOfHessian.Max(); // μ double mu = initialMu * diagonalOfHessian.Max(); // μ
double nu = 2; // ν double nu = 2; // ν
int iterations = 0; int iterations = 0;
while (iterations < maximumIterations && exitCondition == ExitCondition.None) while (iterations < maximumIterations && exitCondition == ExitCondition.None)
@ -155,7 +155,7 @@ namespace MathNet.Numerics.Optimization
while (true) while (true)
{ {
Hessian.SetDiagonal(Hessian.Diagonal() + mu); // hessian[i, i] = hessian[i, i] + mu; Hessian.SetDiagonal(Hessian.Diagonal() + mu); // hessian[i, i] = hessian[i, i] + mu;
// solve normal equations // solve normal equations
Pstep = Hessian.Solve(-Gradient); Pstep = Hessian.Solve(-Gradient);
@ -193,7 +193,7 @@ namespace MathNet.Numerics.Optimization
jac = EvaluateJacobian(objective, P); jac = EvaluateJacobian(objective, P);
Gradient = jac.Item1; // objective.Gradient; Gradient = jac.Item1; // objective.Gradient;
Hessian = jac.Item2; // objective.Hessian; Hessian = jac.Item2; // objective.Hessian;
diagonalOfHessian = Hessian.Diagonal(); diagonalOfHessian = Hessian.Diagonal();
// if ||g||_oo <= gtol, found and stop // if ||g||_oo <= gtol, found and stop
if (Gradient.InfinityNorm() <= gradientTolerance) if (Gradient.InfinityNorm() <= gradientTolerance)

3
src/Numerics/Optimization/LimitedMemoryBfgsMinimizer.cs

@ -98,7 +98,6 @@ namespace MathNet.Numerics.Optimization
var candidate = lineSearchResult.FunctionInfoAtMinimum; var candidate = lineSearchResult.FunctionInfoAtMinimum;
ValidateGradientAndObjective(candidate); ValidateGradientAndObjective(candidate);
var gradient = candidate.Gradient;
var step = candidate.Point - initialGuess; var step = candidate.Point - initialGuess;
var yk = candidate.Gradient - previousPoint.Gradient; var yk = candidate.Gradient - previousPoint.Gradient;
var ykhistory = new List<Vector<double>>() {yk}; var ykhistory = new List<Vector<double>>() {yk};
@ -155,7 +154,7 @@ namespace MathNet.Numerics.Optimization
return new MinimizationWithLineSearchResult(candidate, iterations, ExitCondition.AbsoluteGradient, totalLineSearchSteps, iterationsWithNontrivialLineSearch); return new MinimizationWithLineSearchResult(candidate, iterations, ExitCondition.AbsoluteGradient, totalLineSearchSteps, iterationsWithNontrivialLineSearch);
} }
private Vector<double> ApplyLbfgsUpdate(IObjectiveFunction previousPoint, List<Vector<double>> ykhistory, List<Vector<double>> skhistory, List<double> rhokhistory) Vector<double> ApplyLbfgsUpdate(IObjectiveFunction previousPoint, List<Vector<double>> ykhistory, List<Vector<double>> skhistory, List<double> rhokhistory)
{ {
var q = previousPoint.Gradient.Clone(); var q = previousPoint.Gradient.Clone();
var alphas = new Stack<double>(); var alphas = new Stack<double>();

2
src/Numerics/Optimization/LineSearch/LineSearchResult.cs

@ -31,7 +31,7 @@ namespace MathNet.Numerics.Optimization.LineSearch
{ {
public class LineSearchResult : MinimizationResult public class LineSearchResult : MinimizationResult
{ {
public double FinalStep { get; private set; } public double FinalStep { get; }
public LineSearchResult(IObjectiveFunction functionInfo, int iterations, double finalStep, ExitCondition reasonForExit) public LineSearchResult(IObjectiveFunction functionInfo, int iterations, double finalStep, ExitCondition reasonForExit)
: base(functionInfo, iterations, reasonForExit) : base(functionInfo, iterations, reasonForExit)

4
src/Numerics/Optimization/MinimizationWithLineSearchResult.cs

@ -31,8 +31,8 @@ namespace MathNet.Numerics.Optimization
{ {
public class MinimizationWithLineSearchResult : MinimizationResult public class MinimizationWithLineSearchResult : MinimizationResult
{ {
public int TotalLineSearchIterations { get; private set; } public int TotalLineSearchIterations { get; }
public int IterationsWithNonTrivialLineSearch { get; private set; } public int IterationsWithNonTrivialLineSearch { get; }
public MinimizationWithLineSearchResult(IObjectiveFunction functionInfo, int iterations, ExitCondition reasonForExit, int totalLineSearchIterations, int iterationsWithNonTrivialLineSearch) public MinimizationWithLineSearchResult(IObjectiveFunction functionInfo, int iterations, ExitCondition reasonForExit, int totalLineSearchIterations, int iterationsWithNonTrivialLineSearch)
: base(functionInfo, iterations, reasonForExit) : base(functionInfo, iterations, reasonForExit)

14
src/Numerics/Optimization/NelderMeadSimplex.cs

@ -122,13 +122,12 @@ namespace MathNet.Numerics.Optimization
int numDimensions = simplexConstants.Length; int numDimensions = simplexConstants.Length;
int numVertices = numDimensions + 1; int numVertices = numDimensions + 1;
Vector<double>[] vertices = InitializeVertices(simplexConstants); Vector<double>[] vertices = InitializeVertices(simplexConstants);
double[] errorValues = new double[numVertices];
int evaluationCount = 0; int evaluationCount = 0;
ExitCondition exitCondition = ExitCondition.None; ExitCondition exitCondition = ExitCondition.None;
ErrorProfile errorProfile; ErrorProfile errorProfile;
errorValues = InitializeErrorValues(vertices, objectiveFunction); double[] errorValues = InitializeErrorValues(vertices, objectiveFunction);
int numTimesHasConverged = 0; int numTimesHasConverged = 0;
// iterate until we converge, or complete our permitted number of iterations // iterate until we converge, or complete our permitted number of iterations
@ -219,14 +218,7 @@ namespace MathNet.Numerics.Optimization
double range = 2 * Math.Abs(errorValues[errorProfile.HighestIndex] - errorValues[errorProfile.LowestIndex]) / double range = 2 * Math.Abs(errorValues[errorProfile.HighestIndex] - errorValues[errorProfile.LowestIndex]) /
(Math.Abs(errorValues[errorProfile.HighestIndex]) + Math.Abs(errorValues[errorProfile.LowestIndex]) + JITTER); (Math.Abs(errorValues[errorProfile.HighestIndex]) + Math.Abs(errorValues[errorProfile.LowestIndex]) + JITTER);
if (range < convergenceTolerance) return range < convergenceTolerance;
{
return true;
}
else
{
return false;
}
} }
/// <summary> /// <summary>
@ -380,7 +372,7 @@ namespace MathNet.Numerics.Optimization
sealed class SimplexConstant sealed class SimplexConstant
{ {
public SimplexConstant(double value, double initialPerturbation) SimplexConstant(double value, double initialPerturbation)
{ {
Value = value; Value = value;
InitialPerturbation = initialPerturbation; InitialPerturbation = initialPerturbation;

2
src/Numerics/Optimization/NonlinearMinimizationResult.cs

@ -44,7 +44,7 @@ namespace MathNet.Numerics.Optimization
EvaluateCovariance(modelInfo); EvaluateCovariance(modelInfo);
} }
private void EvaluateCovariance(IObjectiveModel objective) void EvaluateCovariance(IObjectiveModel objective)
{ {
objective.EvaluateAt(objective.Point); // Hessian may be not yet updated. objective.EvaluateAt(objective.Point); // Hessian may be not yet updated.

33
src/Numerics/Optimization/NonlinearMinimizerBase.cs

@ -41,7 +41,7 @@ namespace MathNet.Numerics.Optimization
/// </summary> /// </summary>
public Vector<double> Scales { get; private set; } public Vector<double> Scales { get; private set; }
private bool IsBounded => LowerBound != null || UpperBound != null || Scales != null; bool IsBounded => LowerBound != null || UpperBound != null || Scales != null;
protected NonlinearMinimizerBase(double gradientTolerance = 1E-18, double stepTolerance = 1E-18, double functionTolerance = 1E-18, int maximumIterations = -1) protected NonlinearMinimizerBase(double gradientTolerance = 1E-18, double stepTolerance = 1E-18, double functionTolerance = 1E-18, int maximumIterations = -1)
{ {
@ -55,7 +55,7 @@ namespace MathNet.Numerics.Optimization
{ {
if (parameters == null) if (parameters == null)
{ {
throw new ArgumentNullException("parameters"); throw new ArgumentNullException(nameof(parameters));
} }
if (lowerBound != null && lowerBound.Count(x => double.IsInfinity(x) || double.IsNaN(x)) > 0) if (lowerBound != null && lowerBound.Count(x => double.IsInfinity(x) || double.IsNaN(x)) > 0)
@ -74,7 +74,7 @@ namespace MathNet.Numerics.Optimization
} }
if (upperBound != null && upperBound.Count != parameters.Count) if (upperBound != null && upperBound.Count != parameters.Count)
{ {
throw new ArgumentException("The upper bounds can't have different size from the parameetrs."); throw new ArgumentException("The upper bounds can't have different size from the parameters.");
} }
UpperBound = upperBound; UpperBound = upperBound;
@ -174,7 +174,8 @@ namespace MathNet.Numerics.Optimization
return Pint; return Pint;
} }
else if (LowerBound != null && UpperBound == null)
if (LowerBound != null && UpperBound == null)
{ {
for (int i = 0; i < Pext.Count; i++) for (int i = 0; i < Pext.Count; i++)
{ {
@ -185,7 +186,8 @@ namespace MathNet.Numerics.Optimization
return Pint; return Pint;
} }
else if (LowerBound == null && UpperBound != null)
if (LowerBound == null && UpperBound != null)
{ {
for (int i = 0; i < Pext.Count; i++) for (int i = 0; i < Pext.Count; i++)
{ {
@ -196,7 +198,8 @@ namespace MathNet.Numerics.Optimization
return Pint; return Pint;
} }
else if (Scales != null)
if (Scales != null)
{ {
for (int i = 0; i < Pext.Count; i++) for (int i = 0; i < Pext.Count; i++)
{ {
@ -222,7 +225,8 @@ namespace MathNet.Numerics.Optimization
return Pext; return Pext;
} }
else if (LowerBound != null && UpperBound == null)
if (LowerBound != null && UpperBound == null)
{ {
for (int i = 0; i < Pint.Count; i++) for (int i = 0; i < Pint.Count; i++)
{ {
@ -233,7 +237,8 @@ namespace MathNet.Numerics.Optimization
return Pext; return Pext;
} }
else if (LowerBound == null && UpperBound != null)
if (LowerBound == null && UpperBound != null)
{ {
for (int i = 0; i < Pint.Count; i++) for (int i = 0; i < Pint.Count; i++)
{ {
@ -244,7 +249,8 @@ namespace MathNet.Numerics.Optimization
return Pext; return Pext;
} }
else if (Scales != null)
if (Scales != null)
{ {
for (int i = 0; i < Pint.Count; i++) for (int i = 0; i < Pint.Count; i++)
{ {
@ -269,7 +275,8 @@ namespace MathNet.Numerics.Optimization
} }
return scale; return scale;
} }
else if (LowerBound != null && UpperBound == null)
if (LowerBound != null && UpperBound == null)
{ {
for (int i = 0; i < Pint.Count; i++) for (int i = 0; i < Pint.Count; i++)
{ {
@ -279,7 +286,8 @@ namespace MathNet.Numerics.Optimization
} }
return scale; return scale;
} }
else if (LowerBound == null && UpperBound != null)
if (LowerBound == null && UpperBound != null)
{ {
for (int i = 0; i < Pint.Count; i++) for (int i = 0; i < Pint.Count; i++)
{ {
@ -289,7 +297,8 @@ namespace MathNet.Numerics.Optimization
} }
return scale; return scale;
} }
else if (Scales != null)
if (Scales != null)
{ {
return Scales; return Scales;
} }

10
src/Numerics/Optimization/ObjectiveFunction.cs

@ -146,7 +146,7 @@ namespace MathNet.Numerics.Optimization
Func<Vector<double>, double, Vector<double>> derivatives, Func<Vector<double>, double, Vector<double>> derivatives,
Vector<double> observedX, Vector<double> observedY, Vector<double> weight = null) Vector<double> observedX, Vector<double> observedY, Vector<double> weight = null)
{ {
Vector<double> func(Vector<double> point, Vector<double> x) Vector<double> Func(Vector<double> point, Vector<double> x)
{ {
var functionValues = CreateVector.Dense<double>(x.Count); var functionValues = CreateVector.Dense<double>(x.Count);
for (int i = 0; i < x.Count; i++) for (int i = 0; i < x.Count; i++)
@ -157,7 +157,7 @@ namespace MathNet.Numerics.Optimization
return functionValues; return functionValues;
} }
Matrix<double> prime(Vector<double> point, Vector<double> x) Matrix<double> Prime(Vector<double> point, Vector<double> x)
{ {
var derivativeValues = CreateMatrix.Dense<double>(x.Count, point.Count); var derivativeValues = CreateMatrix.Dense<double>(x.Count, point.Count);
for (int i = 0; i < x.Count; i++) for (int i = 0; i < x.Count; i++)
@ -168,7 +168,7 @@ namespace MathNet.Numerics.Optimization
return derivativeValues; return derivativeValues;
} }
var objective = new NonlinearObjectiveFunction(func, prime); var objective = new NonlinearObjectiveFunction(Func, Prime);
objective.SetObserved(observedX, observedY, weight); objective.SetObserved(observedX, observedY, weight);
return objective; return objective;
} }
@ -180,7 +180,7 @@ namespace MathNet.Numerics.Optimization
Vector<double> observedX, Vector<double> observedY, Vector<double> weight = null, Vector<double> observedX, Vector<double> observedY, Vector<double> weight = null,
int accuracyOrder = 2) int accuracyOrder = 2)
{ {
Vector<double> func(Vector<double> point, Vector<double> x) Vector<double> Func(Vector<double> point, Vector<double> x)
{ {
var functionValues = CreateVector.Dense<double>(x.Count); var functionValues = CreateVector.Dense<double>(x.Count);
for (int i = 0; i < x.Count; i++) for (int i = 0; i < x.Count; i++)
@ -191,7 +191,7 @@ namespace MathNet.Numerics.Optimization
return functionValues; return functionValues;
} }
var objective = new NonlinearObjectiveFunction(func, accuracyOrder: accuracyOrder); var objective = new NonlinearObjectiveFunction(Func, accuracyOrder: accuracyOrder);
objective.SetObserved(observedX, observedY, weight); objective.SetObserved(observedX, observedY, weight);
return objective; return objective;
} }

6
src/Numerics/Optimization/ObjectiveFunctions/ForwardDifferenceGradientObjectiveFunction.cs

@ -48,9 +48,9 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
protected Vector<double> LowerBound { get; set; } protected Vector<double> LowerBound { get; set; }
protected Vector<double> UpperBound { get; set; } protected Vector<double> UpperBound { get; set; }
protected bool ValueEvaluated { get; set; } = false; protected bool ValueEvaluated { get; set; }
protected bool GradientEvaluated { get; set; } = false; protected bool GradientEvaluated { get; set; }
private Vector<double> _gradient; Vector<double> _gradient;
public double MinimumIncrement { get; set; } public double MinimumIncrement { get; set; }
public double RelativeIncrement { get; set; } public double RelativeIncrement { get; set; }

4
src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunction.cs

@ -79,8 +79,8 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
}; };
} }
public bool IsGradientSupported { get; private set; } public bool IsGradientSupported { get; }
public bool IsHessianSupported { get; private set; } public bool IsHessianSupported { get; }
public void EvaluateAt(Vector<double> point) public void EvaluateAt(Vector<double> point)
{ {

4
src/Numerics/Optimization/ObjectiveFunctions/LazyObjectiveFunctionBase.cs

@ -66,8 +66,8 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
return fork; return fork;
} }
public bool IsGradientSupported { get; private set; } public bool IsGradientSupported { get; }
public bool IsHessianSupported { get; private set; } public bool IsHessianSupported { get; }
public void EvaluateAt(Vector<double> point) public void EvaluateAt(Vector<double> point)
{ {

168
src/Numerics/Optimization/ObjectiveFunctions/NonlinearObjectiveFunction.cs

@ -9,20 +9,20 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
{ {
#region Private Variables #region Private Variables
readonly Func<Vector<double>, Vector<double>, Vector<double>> userFunction; // (p, x) => f(x; p) readonly Func<Vector<double>, Vector<double>, Vector<double>> _userFunction; // (p, x) => f(x; p)
readonly Func<Vector<double>, Vector<double>, Matrix<double>> userDerivative; // (p, x) => df(x; p)/dp readonly Func<Vector<double>, Vector<double>, Matrix<double>> _userDerivative; // (p, x) => df(x; p)/dp
readonly int accuracyOrder; // the desired accuracy order to evaluate the jacobian by numerical approximaiton. readonly int _accuracyOrder; // the desired accuracy order to evaluate the jacobian by numerical approximaiton.
Vector<double> coefficients; Vector<double> _coefficients;
bool hasFunctionValue; bool _hasFunctionValue;
double functionValue; // the residual sum of squares, residuals * residuals. double _functionValue; // the residual sum of squares, residuals * residuals.
Vector<double> residuals; // the weighted error values Vector<double> _residuals; // the weighted error values
bool hasJacobianValue; bool _hasJacobianValue;
Matrix<double> jacobianValue; // the Jacobian matrix. Matrix<double> _jacobianValue; // the Jacobian matrix.
Vector<double> gradientValue; // the Gradient vector. Vector<double> _gradientValue; // the Gradient vector.
Matrix<double> hessianValue; // the Hessian matrix. Matrix<double> _hessianValue; // the Hessian matrix.
#endregion Private Variables #endregion Private Variables
@ -42,7 +42,7 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
/// Set or get the values of the weights for the observations. /// Set or get the values of the weights for the observations.
/// </summary> /// </summary>
public Matrix<double> Weights { get; private set; } public Matrix<double> Weights { get; private set; }
private Vector<double> L; // Weights = LL' Vector<double> L; // Weights = LL'
/// <summary> /// <summary>
/// Get whether parameters are fixed or free. /// Get whether parameters are fixed or free.
@ -69,7 +69,7 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
var df = NumberOfObservations - NumberOfParameters; var df = NumberOfObservations - NumberOfParameters;
if (IsFixed != null) if (IsFixed != null)
{ {
df = df + IsFixed.Count(p => p == true); df = df + IsFixed.Count(p => p);
} }
return df; return df;
} }
@ -90,40 +90,40 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
public NonlinearObjectiveFunction(Func<Vector<double>, Vector<double>, Vector<double>> function, public NonlinearObjectiveFunction(Func<Vector<double>, Vector<double>, Vector<double>> function,
Func<Vector<double>, Vector<double>, Matrix<double>> derivative = null, int accuracyOrder = 2) Func<Vector<double>, Vector<double>, Matrix<double>> derivative = null, int accuracyOrder = 2)
{ {
this.userFunction = function; _userFunction = function;
this.userDerivative = derivative; _userDerivative = derivative;
this.accuracyOrder = Math.Min(6, Math.Max(1, accuracyOrder)); _accuracyOrder = Math.Min(6, Math.Max(1, accuracyOrder));
} }
public IObjectiveModel Fork() public IObjectiveModel Fork()
{ {
return new NonlinearObjectiveFunction(userFunction, userDerivative, accuracyOrder) return new NonlinearObjectiveFunction(_userFunction, _userDerivative, _accuracyOrder)
{ {
ObservedX = ObservedX, ObservedX = ObservedX,
ObservedY = ObservedY, ObservedY = ObservedY,
Weights = Weights, Weights = Weights,
coefficients = coefficients, _coefficients = _coefficients,
hasFunctionValue = hasFunctionValue, _hasFunctionValue = _hasFunctionValue,
functionValue = functionValue, _functionValue = _functionValue,
hasJacobianValue = hasJacobianValue, _hasJacobianValue = _hasJacobianValue,
jacobianValue = jacobianValue, _jacobianValue = _jacobianValue,
gradientValue = gradientValue, _gradientValue = _gradientValue,
hessianValue = hessianValue _hessianValue = _hessianValue
}; };
} }
public IObjectiveModel CreateNew() public IObjectiveModel CreateNew()
{ {
return new NonlinearObjectiveFunction(userFunction, userDerivative, accuracyOrder); return new NonlinearObjectiveFunction(_userFunction, _userDerivative, _accuracyOrder);
} }
/// <summary> /// <summary>
/// Set or get the values of the parameters. /// Set or get the values of the parameters.
/// </summary> /// </summary>
public Vector<double> Point => coefficients; public Vector<double> Point => _coefficients;
/// <summary> /// <summary>
/// Get the y-values of the fitted model that correspond to the independent values. /// Get the y-values of the fitted model that correspond to the independent values.
@ -137,12 +137,12 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
{ {
get get
{ {
if (!hasFunctionValue) if (!_hasFunctionValue)
{ {
EvaluateFunction(); EvaluateFunction();
hasFunctionValue = true; _hasFunctionValue = true;
} }
return functionValue; return _functionValue;
} }
} }
@ -153,12 +153,12 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
{ {
get get
{ {
if (!hasJacobianValue) if (!_hasJacobianValue)
{ {
EvaluateJacobian(); EvaluateJacobian();
hasJacobianValue = true; _hasJacobianValue = true;
} }
return gradientValue; return _gradientValue;
} }
} }
@ -169,12 +169,12 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
{ {
get get
{ {
if (!hasJacobianValue) if (!_hasJacobianValue)
{ {
EvaluateJacobian(); EvaluateJacobian();
hasJacobianValue = true; _hasJacobianValue = true;
} }
return hessianValue; return _hessianValue;
} }
} }
@ -230,17 +230,13 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
/// <param name="isFixed">The list to the parameters fix or free.</param> /// <param name="isFixed">The list to the parameters fix or free.</param>
public void SetParameters(Vector<double> initialGuess, List<bool> isFixed = null) public void SetParameters(Vector<double> initialGuess, List<bool> isFixed = null)
{ {
if (initialGuess == null) _coefficients = initialGuess ?? throw new ArgumentNullException(nameof(initialGuess));
{
throw new ArgumentNullException("initialGuess");
}
coefficients = initialGuess;
if (isFixed != null && isFixed.Count != initialGuess.Count) if (isFixed != null && isFixed.Count != initialGuess.Count)
{ {
throw new ArgumentException("The isFixed can't have different size from the initial guess."); throw new ArgumentException("The isFixed can't have different size from the initial guess.");
} }
if (isFixed != null && isFixed.Count(p => p == true) == isFixed.Count) if (isFixed != null && isFixed.Count(p => p) == isFixed.Count)
{ {
throw new ArgumentException("All the parameters can't be fixed."); throw new ArgumentException("All the parameters can't be fixed.");
} }
@ -251,72 +247,70 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
{ {
if (parameters == null) if (parameters == null)
{ {
throw new ArgumentNullException("parameters"); throw new ArgumentNullException(nameof(parameters));
} }
if (parameters.Count(p => double.IsNaN(p) || double.IsInfinity(p)) > 0) if (parameters.Count(p => double.IsNaN(p) || double.IsInfinity(p)) > 0)
{ {
throw new ArgumentException("The parameters must be finite."); throw new ArgumentException("The parameters must be finite.");
} }
coefficients = parameters; _coefficients = parameters;
hasFunctionValue = false; _hasFunctionValue = false;
hasJacobianValue = false; _hasJacobianValue = false;
jacobianValue = null; _jacobianValue = null;
gradientValue = null; _gradientValue = null;
hessianValue = null; _hessianValue = null;
} }
public IObjectiveFunction ToObjectiveFunction() public IObjectiveFunction ToObjectiveFunction()
{ {
Tuple<double, Vector<double>, Matrix<double>> function(Vector<double> point) Tuple<double, Vector<double>, Matrix<double>> Function(Vector<double> point)
{ {
EvaluateAt(point); EvaluateAt(point);
return new Tuple<double, Vector<double>, Matrix<double>>(Value, Gradient, Hessian); return new Tuple<double, Vector<double>, Matrix<double>>(Value, Gradient, Hessian);
} }
var objective = new GradientHessianObjectiveFunction(function); var objective = new GradientHessianObjectiveFunction(Function);
return objective; return objective;
} }
#region Private Methods #region Private Methods
private void EvaluateFunction() void EvaluateFunction()
{ {
// Calculates the residuals, (y[i] - f(x[i]; p)) * L[i] // Calculates the residuals, (y[i] - f(x[i]; p)) * L[i]
if (ModelValues == null) if (ModelValues == null)
{ {
ModelValues = Vector<double>.Build.Dense(NumberOfObservations); ModelValues = Vector<double>.Build.Dense(NumberOfObservations);
} }
ModelValues = userFunction(Point, ObservedX); ModelValues = _userFunction(Point, ObservedX);
FunctionEvaluations++; FunctionEvaluations++;
// calculate the weighted residuals // calculate the weighted residuals
residuals = (Weights == null) _residuals = (Weights == null)
? ObservedY - ModelValues ? ObservedY - ModelValues
: (ObservedY - ModelValues).PointwiseMultiply(L); : (ObservedY - ModelValues).PointwiseMultiply(L);
// Calculate the residual sum of squares // Calculate the residual sum of squares
functionValue = residuals.DotProduct(residuals); _functionValue = _residuals.DotProduct(_residuals);
return;
} }
private void EvaluateJacobian() void EvaluateJacobian()
{ {
// Calculates the jacobian of x and p. // Calculates the jacobian of x and p.
if (userDerivative != null) if (_userDerivative != null)
{ {
// analytical jacobian // analytical jacobian
jacobianValue = userDerivative(Point, ObservedX); _jacobianValue = _userDerivative(Point, ObservedX);
JacobianEvaluations++; JacobianEvaluations++;
} }
else else
{ {
// numerical jacobian // numerical jacobian
jacobianValue = NumericalJacobian(Point, ModelValues, accuracyOrder); _jacobianValue = NumericalJacobian(Point, ModelValues, _accuracyOrder);
FunctionEvaluations += accuracyOrder; FunctionEvaluations += _accuracyOrder;
} }
// weighted jacobian // weighted jacobian
@ -327,23 +321,23 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
if (IsFixed != null && IsFixed[j]) if (IsFixed != null && IsFixed[j])
{ {
// if j-th parameter is fixed, set J[i, j] = 0 // if j-th parameter is fixed, set J[i, j] = 0
jacobianValue[i, j] = 0.0; _jacobianValue[i, j] = 0.0;
} }
else if (Weights != null) else if (Weights != null)
{ {
jacobianValue[i, j] = jacobianValue[i, j] * L[i]; _jacobianValue[i, j] = _jacobianValue[i, j] * L[i];
} }
} }
} }
// Gradient, g = -J'W(y − f(x; p)) = -J'L(L'E) = -J'LR // Gradient, g = -J'W(y − f(x; p)) = -J'L(L'E) = -J'LR
gradientValue = -jacobianValue.Transpose() * residuals; _gradientValue = -_jacobianValue.Transpose() * _residuals;
// approximated Hessian, H = J'WJ + ∑LRiHi ~ J'WJ near the minimum // approximated Hessian, H = J'WJ + ∑LRiHi ~ J'WJ near the minimum
hessianValue = jacobianValue.Transpose() * jacobianValue; _hessianValue = _jacobianValue.Transpose() * _jacobianValue;
} }
private Matrix<double> NumericalJacobian(Vector<double> parameters, Vector<double> currentValues, int accuracyOrder = 2) Matrix<double> NumericalJacobian(Vector<double> parameters, Vector<double> currentValues, int accuracyOrder = 2)
{ {
const double sqrtEpsilon = 1.4901161193847656250E-8; // sqrt(machineEpsilon) const double sqrtEpsilon = 1.4901161193847656250E-8; // sqrt(machineEpsilon)
@ -359,12 +353,12 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
if (accuracyOrder >= 6) if (accuracyOrder >= 6)
{ {
// f'(x) = {- f(x - 3h) + 9f(x - 2h) - 45f(x - h) + 45f(x + h) - 9f(x + 2h) + f(x + 3h)} / 60h + O(h^6) // f'(x) = {- f(x - 3h) + 9f(x - 2h) - 45f(x - h) + 45f(x + h) - 9f(x + 2h) + f(x + 3h)} / 60h + O(h^6)
var f1 = userFunction(parameters - 3 * h, ObservedX); var f1 = _userFunction(parameters - 3 * h, ObservedX);
var f2 = userFunction(parameters - 2 * h, ObservedX); var f2 = _userFunction(parameters - 2 * h, ObservedX);
var f3 = userFunction(parameters - h, ObservedX); var f3 = _userFunction(parameters - h, ObservedX);
var f4 = userFunction(parameters + h, ObservedX); var f4 = _userFunction(parameters + h, ObservedX);
var f5 = userFunction(parameters + 2 * h, ObservedX); var f5 = _userFunction(parameters + 2 * h, ObservedX);
var f6 = userFunction(parameters + 3 * h, ObservedX); var f6 = _userFunction(parameters + 3 * h, ObservedX);
var prime = (-f1 + 9 * f2 - 45 * f3 + 45 * f4 - 9 * f5 + f6) / (60 * h[j]); var prime = (-f1 + 9 * f2 - 45 * f3 + 45 * f4 - 9 * f5 + f6) / (60 * h[j]);
derivertives.SetColumn(j, prime); derivertives.SetColumn(j, prime);
@ -373,11 +367,11 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
{ {
// f'(x) = {-137f(x) + 300f(x + h) - 300f(x + 2h) + 200f(x + 3h) - 75f(x + 4h) + 12f(x + 5h)} / 60h + O(h^5) // f'(x) = {-137f(x) + 300f(x + h) - 300f(x + 2h) + 200f(x + 3h) - 75f(x + 4h) + 12f(x + 5h)} / 60h + O(h^5)
var f1 = currentValues; var f1 = currentValues;
var f2 = userFunction(parameters + h, ObservedX); var f2 = _userFunction(parameters + h, ObservedX);
var f3 = userFunction(parameters + 2 * h, ObservedX); var f3 = _userFunction(parameters + 2 * h, ObservedX);
var f4 = userFunction(parameters + 3 * h, ObservedX); var f4 = _userFunction(parameters + 3 * h, ObservedX);
var f5 = userFunction(parameters + 4 * h, ObservedX); var f5 = _userFunction(parameters + 4 * h, ObservedX);
var f6 = userFunction(parameters + 5 * h, ObservedX); var f6 = _userFunction(parameters + 5 * h, ObservedX);
var prime = (-137 * f1 + 300 * f2 - 300 * f3 + 200 * f4 - 75 * f5 + 12 * f6) / (60 * h[j]); var prime = (-137 * f1 + 300 * f2 - 300 * f3 + 200 * f4 - 75 * f5 + 12 * f6) / (60 * h[j]);
derivertives.SetColumn(j, prime); derivertives.SetColumn(j, prime);
@ -385,10 +379,10 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
else if (accuracyOrder == 4) else if (accuracyOrder == 4)
{ {
// f'(x) = {f(x - 2h) - 8f(x - h) + 8f(x + h) - f(x + 2h)} / 12h + O(h^4) // f'(x) = {f(x - 2h) - 8f(x - h) + 8f(x + h) - f(x + 2h)} / 12h + O(h^4)
var f1 = userFunction(parameters - 2 * h, ObservedX); var f1 = _userFunction(parameters - 2 * h, ObservedX);
var f2 = userFunction(parameters - h, ObservedX); var f2 = _userFunction(parameters - h, ObservedX);
var f3 = userFunction(parameters + h, ObservedX); var f3 = _userFunction(parameters + h, ObservedX);
var f4 = userFunction(parameters + 2 * h, ObservedX); var f4 = _userFunction(parameters + 2 * h, ObservedX);
var prime = (f1 - 8 * f2 + 8 * f3 - f4) / (12 * h[j]); var prime = (f1 - 8 * f2 + 8 * f3 - f4) / (12 * h[j]);
derivertives.SetColumn(j, prime); derivertives.SetColumn(j, prime);
@ -397,9 +391,9 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
{ {
// f'(x) = {-11f(x) + 18f(x + h) - 9f(x + 2h) + 2f(x + 3h)} / 6h + O(h^3) // f'(x) = {-11f(x) + 18f(x + h) - 9f(x + 2h) + 2f(x + 3h)} / 6h + O(h^3)
var f1 = currentValues; var f1 = currentValues;
var f2 = userFunction(parameters + h, ObservedX); var f2 = _userFunction(parameters + h, ObservedX);
var f3 = userFunction(parameters + 2 * h, ObservedX); var f3 = _userFunction(parameters + 2 * h, ObservedX);
var f4 = userFunction(parameters + 3 * h, ObservedX); var f4 = _userFunction(parameters + 3 * h, ObservedX);
var prime = (-11 * f1 + 18 * f2 - 9 * f3 + 2 * f4) / (6 * h[j]); var prime = (-11 * f1 + 18 * f2 - 9 * f3 + 2 * f4) / (6 * h[j]);
derivertives.SetColumn(j, prime); derivertives.SetColumn(j, prime);
@ -407,8 +401,8 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
else if (accuracyOrder == 2) else if (accuracyOrder == 2)
{ {
// f'(x) = {f(x + h) - f(x - h)} / 2h + O(h^2) // f'(x) = {f(x + h) - f(x - h)} / 2h + O(h^2)
var f1 = userFunction(parameters + h, ObservedX); var f1 = _userFunction(parameters + h, ObservedX);
var f2 = userFunction(parameters - h, ObservedX); var f2 = _userFunction(parameters - h, ObservedX);
var prime = (f1 - f2) / (2 * h[j]); var prime = (f1 - f2) / (2 * h[j]);
derivertives.SetColumn(j, prime); derivertives.SetColumn(j, prime);
@ -417,7 +411,7 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
{ {
// f'(x) = {- f(x) + f(x + h)} / h + O(h) // f'(x) = {- f(x) + f(x + h)} / h + O(h)
var f1 = currentValues; var f1 = currentValues;
var f2 = userFunction(parameters + h, ObservedX); var f2 = _userFunction(parameters + h, ObservedX);
var prime = (-f1 + f2) / h[j]; var prime = (-f1 + f2) / h[j];
derivertives.SetColumn(j, prime); derivertives.SetColumn(j, prime);

4
src/Numerics/Optimization/ObjectiveFunctions/ObjectiveFunctionBase.cs

@ -52,8 +52,8 @@ namespace MathNet.Numerics.Optimization.ObjectiveFunctions
return objective; return objective;
} }
public bool IsGradientSupported { get; private set; } public bool IsGradientSupported { get; }
public bool IsHessianSupported { get; private set; } public bool IsHessianSupported { get; }
public void EvaluateAt(Vector<double> point) public void EvaluateAt(Vector<double> point)
{ {

15
src/Numerics/Optimization/TrustRegion/TrustRegionMinimizerBase.cs

@ -21,10 +21,7 @@ namespace MathNet.Numerics.Optimization.TrustRegion
double gradientTolerance = 1E-8, double stepTolerance = 1E-8, double functionTolerance = 1E-8, double radiusTolerance = 1E-8, int maximumIterations = -1) double gradientTolerance = 1E-8, double stepTolerance = 1E-8, double functionTolerance = 1E-8, double radiusTolerance = 1E-8, int maximumIterations = -1)
: base(gradientTolerance, stepTolerance, functionTolerance, maximumIterations) : base(gradientTolerance, stepTolerance, functionTolerance, maximumIterations)
{ {
if (subproblem == null) Subproblem = subproblem ?? throw new ArgumentNullException(nameof(subproblem));
throw new ArgumentNullException("subproblem");
Subproblem = subproblem;
RadiusTolerance = radiusTolerance; RadiusTolerance = radiusTolerance;
} }
@ -38,12 +35,12 @@ namespace MathNet.Numerics.Optimization.TrustRegion
public NonlinearMinimizationResult FindMinimum(IObjectiveModel objective, double[] initialGuess, public NonlinearMinimizationResult FindMinimum(IObjectiveModel objective, double[] initialGuess,
double[] lowerBound = null, double[] upperBound = null, double[] scales = null, bool[] isFixed = null) double[] lowerBound = null, double[] upperBound = null, double[] scales = null, bool[] isFixed = null)
{ {
var lb = (lowerBound == null) ? null : CreateVector.Dense<double>(lowerBound); var lb = (lowerBound == null) ? null : CreateVector.Dense(lowerBound);
var ub = (upperBound == null) ? null : CreateVector.Dense<double>(upperBound); var ub = (upperBound == null) ? null : CreateVector.Dense(upperBound);
var sc = (scales == null) ? null : CreateVector.Dense<double>(scales); var sc = (scales == null) ? null : CreateVector.Dense(scales);
var fx = (isFixed == null) ? null : isFixed.ToList(); var fx = (isFixed == null) ? null : isFixed.ToList();
return Minimum(Subproblem, objective, CreateVector.DenseOfArray<double>(initialGuess), lb, ub, sc, fx, return Minimum(Subproblem, objective, CreateVector.DenseOfArray(initialGuess), lb, ub, sc, fx,
GradientTolerance, StepTolerance, FunctionTolerance, RadiusTolerance, MaximumIterations); GradientTolerance, StepTolerance, FunctionTolerance, RadiusTolerance, MaximumIterations);
} }
@ -102,7 +99,7 @@ namespace MathNet.Numerics.Optimization.TrustRegion
double eta = 0; double eta = 0;
if (objective == null) if (objective == null)
throw new ArgumentNullException("objective"); throw new ArgumentNullException(nameof(objective));
ValidateBounds(initialGuess, lowerBound, upperBound, scales); ValidateBounds(initialGuess, lowerBound, upperBound, scales);

2
src/Numerics/Permutation.cs

@ -42,7 +42,7 @@ namespace MathNet.Numerics
/// <summary> /// <summary>
/// Entry _indices[i] represents the location to which i is permuted to. /// Entry _indices[i] represents the location to which i is permuted to.
/// </summary> /// </summary>
private readonly int[] _indices; readonly int[] _indices;
#endregion fields #endregion fields

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save