Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.02.15;
Скачать: CL | DM;

Вниз

Аппроксимация методом наименьших квадратов   Найти похожие ветки 

 
Marser ©   (2008-04-09 15:00) [0]

Имеется табличное представление некой функции. Требуется найти коэффициенты для её аналитического представления в виде гиперболической:
f(t)=a+b/t
и логарифмической:
f(t)=a+b*ln(t)

Проблема в том, что пока в Рунете не удалось найти ничего по этим функциям. С линейной и полиномиальной аппроксимацией проблем не было, а вот здесь...

Буду рад методикам и особенно рад готовым решениям.


 
MBo ©   (2008-04-09 15:11) [1]

замена переменных
x = 1/t
и
x=ln(t)
сводит задачу к линейной


 
Marser ©   (2008-04-09 15:21) [2]

Т.е. скормить функции линейной аппроксимации для ряда t1..tn значения 1/t1..1/tn ?
Кстати, такая мысль у меня мелькала в голове, и TUser посказывал в аське...


 
Семеныч   (2008-04-09 15:53) [3]

> Marser ©   (09.04.08 15:21) [2]

Да. Определяется формула, сводящая задачу к линейной; по ней делается пересчет табличных значений; решается линейная задача; если надо, то полученные коэффициенты пересчитываются на исходную функцию.


 
Jeer ©   (2008-04-09 16:03) [4]

В общих словах:

type
 TFuncRegress = function(value: TFloat): TFloat;

   TransX: TFuncRegress;
   TransY: TFuncRegress;
   TransA: TFuncRegress;
   TransB: TFuncRegress;

function LinearTransform(value: TFloat): TFloat;
begin
 Result := value;
end;

function BackTransform(value: TFloat): TFloat;
begin
 Result := 1 / value;
end;

function LnTransform(value: TFloat): TFloat;
begin
 Result := Ln(Value);
end;

procedure TRegression.SetRegression(idx: integer);
begin
 Clear;
 fRegType := idx;
 case idx of
// y = a + b * x
   0: begin
       TransX := @LinearTransform;
       TransY := @LinearTransform;
       TransA := @LinearTransform;
       TransB := @LinearTransform;
     end;
// y = a + b * x^2
   1: begin
       TransX := @ParabolicTransform;
       TransY := @LinearTransform;
       TransA := @LinearTransform;
       TransB := @LinearTransform;
     end;
// y = a + b * x^3
   2: begin
       TransX := @CubicTransform;
       TransY := @LinearTransform;
       TransA := @LinearTransform;
       TransB := @LinearTransform;
     end;
// y = a + b / x
   3: begin
       TransX := @BackTransform;
       TransY := @LinearTransform;
       TransA := @LinearTransform;
       TransB := @LinearTransform;
     end;
// y = 1 / (a + b * x)
   4: begin
       TransX := @LinearTransform;
       TransY := @BackTransform;
       TransA := @LinearTransform;
       TransB := @LinearTransform;
     end;
// y = a*b^x
   5: begin
       TransX := @LinearTransform;
       TransY := @LgTransform;
       TransA := @DecTransform;
       TransB := @LinearTransform;
     end;

// y = a*exp(b^x)
   6: begin
       TransX := @LinearTransform;
       TransY := @LnTransform;
       TransA := @ExpTransform;
       TransB := @LinearTransform;
     end;

// y = a*10(b^x)
   7: begin
       TransX := @LinearTransform;
       TransY := @LgTransform;
       TransA := @Power10Transform;
       TransB := @LinearTransform;
     end;

// y = 1 / ( A + B * exp(-x))
   8: begin
       TransX := @ExpNegTransform;
       TransY := @BackTransform;
       TransA := @LinearTransform;
       TransB := @LinearTransform;
     end;

// y = ( A + B * Ln(x))
   9: begin
       TransX := @LnTransform;
       TransY := @LinearTransform;
       TransA := @LinearTransform;
       TransB := @LinearTransform;
     end;

// y =  A * exp ( B / x)
   10: begin
       TransX := @BackTransform;
       TransY := @LnTransform;
       TransA := @ExpTransform;
       TransB := @LinearTransform;
     end;

// y =  A *  x ^5
   11: begin
       TransX := @PowerX5Transform;
       TransY := @LinearTransform;
       TransA := @LinearTransform;
       TransB := @LinearTransform;
     end;

 end;
end; // SetRegression

function TRegression.Next(const X: TFloat; const Y: TFloat = 0): TFloat;
begin
 if fCount = 0 then begin
   fFirstX := X;
   fFirstY := Y;
 end;
 fLastX := X;
 fLastY := Y;

 if X >= fMaxX then fMaxX := X;
 if X < fMinX then fMinX := X;

 if Y >= fMaxY then fMaxY := Y;
 if Y < fMinY then fMinY := Y;

 Result := Add(TransX(X), TransY(Y));

 Inc(fCount);

end {Next value};

function TRegression.Add(const X: TFloat; const Y: TFloat = 0): TFloat;
begin
 fSumX := fSumX + X;
 fSumY := fSumY + Y;
 fSumXX := fSumXX + X * X;
 fSumYY := fSumYY + Y * Y;
 fSumXY := fSumXY + X * Y;
 Result := fSumY;
end {Add value};

procedure TRegression.GetCoeff;
var Qx, Qy, Qxy, Qz: TFloat;
begin
 Qz := fSumY * fSumXX - fSumX * fSumXY;
 Qxy := fCount * fSumXY - fSumX * fSumY;
 Qx := fCount * fSumXX - sqr(fSumX);
 Qy := fCount * fSumYY - sqr(fSumY);

 fA := TransA(Qz / Qx);
 fB := TransB(Qxy / Qx);
 fR := Qxy / sqrt(Qx * Qy);
end;

function TRegression.Calc(value: TFloat): TFloat;
begin
 Result := 0.0;
 case fRegType of
   0: Result := fA + fB * Value; // y = A + B * x
   1: Result := fA + fB * Value * Value; // y = A + B * x^2
   2: Result := fA + fB * Value * Value * Value; // y = A + B * x^3
   3: Result := fA + fB / Value; // y = A + B / x
   4: Result := 1 / (fA + fB * Value); // y = 1 / (A + B * x)
   5: Result := fA * Power(fB, Value); // y = A * B ^ x
   6: Result := fA * Exp(fB * Value); // y = A * exp( B * x )
   7: Result := fA * power(10, fB * Value); // y = A * 10^( B * x )
   8: Result := 1 / (fA + fB * exp(-Value)); // y = 1 / (A + B * exp(-x))
   9: Result := fA + fB * Ln(Value); // y =  (A + B * Ln(-x))
   10: Result := fA * Exp(fB / Value); // y =  A * exp (B / x)
   11: Result := fA + fB * Value * Value * Value * Value * Value;
 end;
end;


 
Jeer ©   (2008-04-09 16:20) [5]

Как это выглядит:
http://slil.ru/25670910


 
Marser ©   (2008-04-09 18:08) [6]

Спасибо, Сергей! Насколько я мог понять по:

function LinearTransform(value: TFloat): TFloat;
begin
Result := value;
end;

function BackTransform(value: TFloat): TFloat;
begin
Result := 1 / value;
end;

function LnTransform(value: TFloat): TFloat;
begin
Result := Ln(Value);
end;


Вы используете тот же принцип замены?


 
Jeer ©   (2008-04-09 18:21) [7]

Так другого, вроде, и не дано:)

Пример на функции y = a*x/(b+x)

Преобразуем к a/y - b/x - 1 = 0
т.к. на реальных данных нуля не будет, то минимизируем сумму кв.
d^2 = sum(a/Yi - b/Xi - 1)^2
Для минимума надо чтобы производные по a и b были равны 0
Откуда
a*sum(1/Yi^2) - b*sum(1/(Xi*Yi) = sum(1/Yi)
a*sum(1/(Xi*Yi)) - b*sum(1/Xi^2) = sum(1/Xi)

Решение дает a и b

Надо учитывать, что вследствии нелинейных преобразований качество на больших шумовых сигналах может оказаться неудовлетворительным.


 
Marser ©   (2008-04-09 18:45) [8]


> Надо учитывать, что вследствии нелинейных преобразований
> качество на больших шумовых сигналах может оказаться неудовлетворительным.
>

Ясно. У меня данные из другой области. Спасибо вам!



Страницы: 1 вся ветка

Текущий архив: 2009.02.15;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.014 c
2-1231171332
sh1k4r1
2009-01-05 19:02
2009.02.15
Excel + Delphi


2-1230487383
inviz
2008-12-28 21:03
2009.02.15
как преобразовать array и caption ?


2-1209619132
FoxikM
2008-05-01 09:18
2009.02.15
Как копировать файлы с "неправильным" именем


8-1189549248
adolis1
2007-09-12 02:20
2009.02.15
програма для начитки текста и его записи в файл


2-1230648345
Nameziz
2008-12-30 17:45
2009.02.15
ReleaseDC