Browse Source

Fit: weighted MultiDim and weighted Polynomial

optimization-3
Christoph Ruegg 13 years ago
parent
commit
2853fe4b9c
  1. 3
      MathNet.Numerics.sln.DotSettings
  2. 19
      src/Numerics/Fit.cs
  3. 22
      src/UnitTests/FitTests.cs

3
MathNet.Numerics.sln.DotSettings

@ -15,6 +15,8 @@
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_BINARY_OPSIGN/@EntryValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_BINARY_OPSIGN/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LINES/@EntryValue">False</s:Boolean> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LINES/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderText/@EntryValue">&lt;copyright file="$FILENAME$" company="Math.NET"&gt;&#xD; <s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderText/@EntryValue">&lt;copyright file="$FILENAME$" company="Math.NET"&gt;&#xD;
@ -66,5 +68,6 @@ OTHER DEALINGS IN THE SOFTWARE.&#xD;
<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>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TFQMR/@EntryIndexedValue">TFQMR</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TFQMR/@EntryIndexedValue">TFQMR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=WH/@EntryIndexedValue">WH</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=WH/@EntryIndexedValue">WH</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/FilterSettingsManager/AttributeFilterXml/@EntryValue">&lt;data /&gt;</s:String> <s:String x:Key="/Default/FilterSettingsManager/AttributeFilterXml/@EntryValue">&lt;data /&gt;</s:String>
<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue">&lt;data&gt;&lt;IncludeFilters /&gt;&lt;ExcludeFilters /&gt;&lt;/data&gt;</s:String></wpf:ResourceDictionary> <s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue">&lt;data&gt;&lt;IncludeFilters /&gt;&lt;ExcludeFilters /&gt;&lt;/data&gt;</s:String></wpf:ResourceDictionary>

19
src/Numerics/Fit.cs

@ -70,6 +70,15 @@ namespace MathNet.Numerics
return MultipleRegression.NormalEquations(x, y); return MultipleRegression.NormalEquations(x, y);
} }
/// <summary>
/// Weighted Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) and weights w to a linear surface y : X -> p0*x0 + p1*x1 + ... + pk*xk,
/// returning its best fitting parameters as [p0, p1, p2, ..., pk] array.
/// </summary>
public static double[] MultiDimWeighted(double[][] x, double[] y, double[] w)
{
return WeightedRegression.Weighted(x, y, w);
}
/// <summary> /// <summary>
/// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to a linear surface y : X -> p0*x0 + p1*x1 + ... + pk*xk, /// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to a linear surface y : X -> p0*x0 + p1*x1 + ... + pk*xk,
/// returning a function y' for the best fitting combination. /// returning a function y' for the best fitting combination.
@ -90,6 +99,16 @@ namespace MathNet.Numerics
return MultipleRegression.QR(design, Vector<double>.Build.Dense(y)).ToArray(); return MultipleRegression.QR(design, Vector<double>.Build.Dense(y)).ToArray();
} }
/// <summary>
/// Weighted Least-Squares fitting the points (x,y) and weights w to a k-order polynomial y : x -> p0 + p1*x + p2*x^2 + ... + pk*x^k,
/// returning its best fitting parameters as [p0, p1, p2, ..., pk] array, compatible with Evaluate.Polynomial.
/// </summary>
public static double[] PolynomialWeighted(double[] x, double[] y, double[] w, int order)
{
var design = Matrix<double>.Build.Dense(x.Length, order + 1, (i, j) => Math.Pow(x[i], j));
return WeightedRegression.Weighted(design, Vector<double>.Build.Dense(y), Matrix<double>.Build.DenseOfDiagonalArray(w)).ToArray();
}
/// <summary> /// <summary>
/// Least-Squares fitting the points (x,y) to a k-order polynomial y : x -> p0 + p1*x + p2*x^2 + ... + pk*x^k, /// Least-Squares fitting the points (x,y) to a k-order polynomial y : x -> p0 + p1*x + p2*x^2 + ... + pk*x^k,
/// returning a function y' for the best fitting polynomial. /// returning a function y' for the best fitting polynomial.

22
src/UnitTests/FitTests.cs

@ -133,6 +133,28 @@ namespace MathNet.Numerics.UnitTests
} }
} }
[Test]
public void FitsToOrder2PolynomialWeighted()
{
// Mathematica: LinearModelFit[{{1,4.986},{2,2.347},{3,2.061},{4,-2.995},{5,-2.352},{6,-5.782}}, {1, x, x^2}, x, Weights -> {0.5, 1.0, 1.0, 1.0, 1.0, 0.5}]
// -> 7.01451 - 2.12819 x + 0.0115 x^2
var x = Enumerable.Range(1, 6).Select(Convert.ToDouble).ToArray();
var y = new[] { 4.986, 2.347, 2.061, -2.995, -2.352, -5.782 };
var respUnweighted = Fit.PolynomialWeighted(x, y, new[] { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }, 2);
Assert.AreEqual(3, respUnweighted.Length);
Assert.AreEqual(6.9703, respUnweighted[0], 1e-4);
Assert.AreEqual(-2.05564, respUnweighted[1], 1e-4);
Assert.AreEqual(-0.00426786, respUnweighted[2], 1e-6);
var resp = Fit.PolynomialWeighted(x, y, new[] { 0.5, 1.0, 1.0, 1.0, 1.0, 0.5 }, 2);
Assert.AreEqual(3, resp.Length);
Assert.AreEqual(7.01451, resp[0], 1e-4);
Assert.AreEqual(-2.12819, resp[1], 1e-4);
Assert.AreEqual(0.0115, resp[2], 1e-6);
}
[Test] [Test]
public void FitsToTrigonometricLinearCombination() public void FitsToTrigonometricLinearCombination()
{ {

Loading…
Cancel
Save