#MathdotNet如何在Math.NET中通过非线性回归找到Herschel-Bulkley模型的参数?

时间:2017-09-30 17:23:38

标签: c# mathdotnet

首先,我要感谢参与这个宏伟项目的每个人,Math.NET救了我的命! 关于线性和非线性回归我几乎没有问题,我是土木工程师,当我攻读硕士学位时,我需要开发一个C#应用程序,根据从测试中获得的数据计算混凝土的流变参数。 其中一个描述混凝土流变行为的模型是“Herschel-Bulkley模型”,它具有以下公式:

y = T + K*x^n

x(剪切速率),y(剪切应力)是从测试中获得的值,而T,K和N是我需要确定的参数。 我知道“T”的值介于0和Ymin之间(Ymin是测试中的最小数据点),所以这就是我所做的: 由于它是非线性方程,我必须使它成为线性的,如下所示: ln(y-T)= ln(K)+ n * ln(x)

创建一个可能的T值数组,从0到Ymin,并尝试等式中的每个值, 然后通过线性回归我找到K和N的值, 然后计算SSD,并将结果存储在一个数组中, 在我完成T的所有可能值之后,我看到哪个具有最小的SSD,并使用它来找到最佳的K和N. 这个方法有效,但我觉得它不像应该的那样聪明或优雅,必须有更好的方法来做到这一点,我希望在这里找到它,它也很慢。 这是我使用的代码:

    public static double HerschelBulkley(double shearRate, double tau0, double k, double n)
{
    var t = tau0 + k * Math.Pow(shearRate, n);
    return t;
}

public static (double Tau0, double K, double N, double DeltaMin, double RSquared) HerschelBulkleyModel(double[] shear, double[] shearRate, double step = 1000.0)
{
    // Calculate the number values from 0.0 to Shear.Min;
    var sm = (int) Math.Floor(shear.Min() * step);
    // Populate the Array of Tau0 with the values from 0 to sm
    var tau0Array = Enumerable.Range(0, sm).Select(t => t / step).ToArray();
    var kArray = new double[sm];
    var nArray = new double[sm];
    var deltaArray = new double[sm];
    var rSquaredArray = new double[sm];
    var shearRateLn = shearRate.Select(s => Math.Log(s)).ToArray();
    for (var i = 0; i < sm; i++)
    {
        var shearLn = shear.Select(s => Math.Log(s - tau0Array[i])).ToArray();
        var param = Fit.Line(shearRateLn, shearLn);
        kArray[i] = Math.Exp(param.Item1);
        nArray[i] = param.Item2;
        var shearHerschel = shearRate.Select(sr => HerschelBulkley(sr, tau0Array[i], kArray[i], nArray[i])).ToArray();
        deltaArray[i] = Distance.SSD(shearHerschel, shear);
        rSquaredArray[i] = GoodnessOfFit.RSquared(shearHerschel, shear);
    }
    var deltaMin = deltaArray.Min();
    var index = Array.IndexOf(deltaArray, deltaMin);
    var tau0 = tau0Array[index];
    var k = kArray[index];
    var n = nArray[index];
    var rSquared = rSquaredArray[index];
    return (tau0, k, n, deltaMin, rSquared);
}

0 个答案:

没有答案