#MathdotNet Как найти параметры модели Гершеля-Балкли с помощью нелинейной регрессии в Math.NET?
Во-первых, я хотел бы поблагодарить всех, кто участвовал в этом великолепном проекте, Math.NET спас мне жизнь! У меня есть несколько вопросов о линейной и нелинейной регрессии, я инженер-строитель, и когда я работал над магистерской работой, мне нужно было разработать приложение на C#, которое рассчитывает реологические параметры бетона на основе данных, полученных в ходе испытаний. Одной из моделей, описывающих реологическое поведение бетона, является "модель Гершеля-Балкли", которая имеет следующую формулу:
y = T + K*x^n
x (скорость сдвига), y (напряжение сдвига) - это значения, полученные из теста, а T,K и N - параметры, которые мне нужно определить. Я знаю, что значение "T" находится в диапазоне от 0 до Ymin (Ymin - это наименьшая точка данных в тесте), поэтому вот что я сделал: так как это нелинейное уравнение, мне пришлось сделать его линейным, например: ln(yT) = ln(K) + n*ln(x)
Создайте массив возможных значений T от 0 до Ymin и попробуйте каждое значение в уравнении, затем с помощью линейной регрессии я найду значения K и N, затем вычислю SSD и сохраню результаты в массиве после того, как I Закончив все возможные значения 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);
}