Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2009.02.15;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.009 c
2-1231418330
bioss
2009-01-08 15:38
2009.02.15
Как перевести каретку в начало текстового файла?


2-1231402706
FEV
2009-01-08 11:18
2009.02.15
Проблема


15-1229929327
Slider007
2008-12-22 10:02
2009.02.15
С днем рождения ! 21 декабря 2008 воскресенье


2-1230629849
LabaN
2008-12-30 12:37
2009.02.15
Смайлы


15-1229502288
zorik
2008-12-17 11:24
2009.02.15
Подскажите реальный пример использования Синглтона





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский