![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Помогите вычислить тенденцию
Twister © (2015-10-13 13:40:00)Никак не могу сообразить.
Допустим есть числа
85
83
81
76
73
82
76
69
62
58
к примеру, как можно определить, что допустим идет тенденция на уменьшение ну или на увеличение и какой-нибудь коэфициент получить этой тенденции? допустим с 5 по 12 число, было уменьшение и скорость или прогресс уменьшения допустим равно стока-то, а с чисел с 3 по 10 стока-то? а лучше не с такого-то числа по такойто, а например с 5 по 12 числа, прогресс уменьшение относительно числа 70 было, вверх или вниз с таким-то коэффициентом?
что-то башку уже сломал всю.
чисел конечно может быть произвольное кол-во.
han_malign (2015-10-28 11:09:00) [1]
> Sha © [21]
> [1] и [3] - это как раз и есть простейший вариант скользящей средней
- смутил ты меня своей delta[i] - это все таки sample[], ну в крайнем случае f[]...
Dmk (2015-10-24 22:24:00) [2]Короче тут вариант с 3-я независимыми графиками:
http://files.expert-graphics.ru/test/Tendency.zip
у меня Delphi XE6.
Dmk (2015-10-24 21:31:00) [3]>получить скорость увеличеня или уменьшения за последние 10 секунд
Суммировать данные только за этот промежуток.
Просто введите временной массив и пишите в него каждую единицу времени значение.
сумма за промежуток времени := n+5 ... n + 14; в итоге 10 секунд начиная с пятой есть то, что вы ищите.
Twister (2015-10-24 18:59:00) [4]Dmk да и всем спасибо
но эту тенденцию как оказалось 1 в 1 я сделал по своему расчету, ну она почти как у Dmk, но результат такой же.
НО
не хватает одного ВАЖНОГО параметра как скорость!
т.е. допустим есть 200 цифр в массиве, она скармливается этой функции (каждая из этих цифр получается раз в секнуду, допустим) и нужно получить скорость увеличеня или уменьшения за последние 10 секунд, ну или 5 секунд или 20 секунд
...Просто поделить время на скорость измеенния....просто сократить десятки или сотки
Sha (2015-10-23 14:36:00) [5][1] и [3] - это как раз и есть простейший вариант скользящей средней
han_malign (2015-10-23 13:44:00) [6]
> Хм, Игорь, а Ваш рабочий код где?
- Игорь - как бэ намекает - что код дожен быть реализацией какого то математически обоснованного алгоритма...
Excel statistical functions: TREND
...
The TREND(known_y's, known_x's, new_x's, constant) function is used to perform Linear Regression. A least squares criterionis used and TREND tries to find the best fit under that criterion. Known_y's represent data on the "dependent variable" and known_x's represent data on one or more "independent variables". The TREND Help file discusses rare cases where the second or third argument may be omitted.
- см. - han_malign © [9]
А для сигналас постоянным шагом дискретизации обычно больше подходит:
https://ru.wikipedia.org/wiki/Скользящая_средняя
brother (2015-10-23 11:23:00) [7]Хм, Игорь, а Ваш рабочий код где? Dmk хотя бы что-то показывает... а Вы?
Игорь Шевченко (2015-10-23 10:28:00) [8]А вы, друзья, как ни садитесь, все в музыканты не годитесь (с)
Работающий код еще не означает, что его можно советовать.
И вообще, в Excel это уже встроено
Dmk (2015-10-22 21:39:00) [9]Вот вариант с Extended:
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Math;
type
TForm2 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
Input1: array[0..17] of extended = (85.2,83.4,81.9,76.1,73.2,82.9,76.8,69.7,62.1,60.3,55.5,50.1,47.7,45.4,34.3,55.8 ,67.1,88.9);//Возрастание
Input2: array[0..18] of extended = (85.3,80.1,85.76,90.89,85.43,80.56,85.4,90.1,85.9,80.12,85.76,90.91,85.45,80.0,8 5.45,90.46,85.5,80.21,85.3);//Стабильность
Input3: array[0..17] of extended = (85.3,84.1,81.89,80.16,89.77,82/35,76.67,75.98,72.9,80.12,82.06,75.01,74.15,73.55,56.89,50.07,48.67,80.22);//Упадок
sr2: array of extended;
implementation
{$R *.dfm}
function TendStr(const AInput: array of extended): string;
var
A: extended;
B: extended;
Pos: integer;
arrEnd: integer;
sr2End: integer;
sumStr: string;
d: extended;
InputSize: integer;
begin
InputSize := Length(AInput);
arrEnd := (InputSize - 1);
sr2End := arrEnd - 1;
SetLength(sr2, arrEnd);
for Pos := 0 to sr2End do
begin
A := AInput[Pos];
B := AInput[Pos + 1];
d := (B - A);
if d > 0 then
sumStr := SumStr + '+' + FloatToStrF(d, ffNumber, 18, 2) else
sumStr := SumStr + FloatToStrF(d, ffNumber, 18, 2);
if Pos <> sr2End then sumStr := sumStr + ', ';
end;//for
sumStr := sumStr + '.';
Result := sumStr;
end;
procedure SetPixel(x, y: integer; AColor: TColor);
begin
Form2.Canvas.Pixels[x, y] := AColor;
Form2.Canvas.Pixels[x - 1, y] := AColor;
Form2.Canvas.Pixels[x - 1, y - 1] := AColor;
Form2.Canvas.Pixels[x, y - 1] := AColor;
Form2.Canvas.Pixels[x + 1, y - 1] := AColor;
Form2.Canvas.Pixels[x + 1, y] := AColor;
Form2.Canvas.Pixels[x + 1, y + 1] := AColor;
Form2.Canvas.Pixels[x, y + 1] := AColor;
Form2.Canvas.Pixels[x - 1, y + 1] := AColor;
end;
function Tend(const AInput: array of extended): extended;
var
A: extended;
B: extended;
Pos: integer;
arrEnd: integer;
sr2End: integer;
sum: extended;
d: extended;
InputSize: integer;
x,y: integer;
x1,y1: integer;
gap: integer;
inv: integer;
begin
sum := 0;
InputSize := Length(AInput);
arrEnd := (InputSize - 1);
sr2End := arrEnd - 1;
SetLength(sr2, arrEnd);
Form2.canvas.Pen.Style := psSolid;
Form2.canvas.Pen.Width := 2;
Form2.canvas.Pen.Color := Rgb(Random($FF), Random($FF), Random($FF));
Form2.canvas.Pen.Mode := pmCopy;
gap := 20;
inv := 200;
for Pos := 0 to sr2End do
begin
A := AInput[Pos];
B := AInput[Pos + 1];
d := (B - A);
sum := sum + d;
x := gap + (gap * Pos);
y := Inv - Round(A);
Form2.Canvas.MoveTo(x, y);
x1 := gap + (gap * (Pos + 1));
y1 := Inv - Round(A + d);
Form2.Canvas.LineTo(x1, y1);
SetPixel(x, y, clBlack);
end;//for
Result := sum;
end;//proc
procedure ShowTend(ASum: extended; AStr: string);
begin
if ASum > 0 then ShowMessage('Возрастание: ' + ' ' + FloatToStrF(ASum, ffNumber, 18, 2) + #13 + AStr);
if ASum = 0 then ShowMessage('Стабильность: ' + ' ' + FloatToStrF(ASum, ffNumber, 18, 2) + #13 + AStr);
if ASum < 0 then ShowMessage('Упадок: ' + ' ' + FloatToStrF(ASum, ffNumber, 18, 2) + #13 + AStr);
end;
procedure TForm2.Button1Click(Sender: TObject);
var
sum: extended;
str: string;
begin
sum := Tend(Input1);
str := TendStr(Input1);
ShowTend(sum, str);
sum := Tend(Input2);
str := TendStr(Input2);
ShowTend(sum, str);
sum := Tend(Input3);
str := TendStr(Input3);
ShowTend(sum, str);
end;
end.
Dmk (2015-10-22 20:25:00) [10]Даже еще короче и проще:
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Math;
type
TForm2 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
Input1: array[0..17] of integer = (85,83,81,76,73,82,76,69,62,60,55,50,47,45,34,55,67,88);//Возрастание
Input2: array[0..18] of integer = (85,80,85,90,85,80,85,90,85,80,85,90,85,80,85,90,85,80,85);//Стабильность
Input3: array[0..17] of integer = (85,84,81,80,89,82,76,75,72,80,82,75,74,73,56,50,48,80);//Упадок
sr2: array of integer;
implementation
{$R *.dfm}
procedure MinMax(const AInput: array of integer);
var
A: integer;
B: integer;
Pos: integer;
arrEnd: integer;
sr2End: integer;
sum: integer;
sumStr: string;
d: integer;
InputSize: integer;
begin
Pos := 0;
sum := 0;
InputSize := Length(AInput);
arrEnd := (InputSize - 1);
sr2End := arrEnd - 1;
SetLength(sr2, arrEnd);
for Pos := 0 to sr2End do
begin
A := AInput[Pos];
B := AInput[Pos + 1];
d := (B - A);
sum := sum + d;
if d > 0 then
sumStr := SumStr + '+' + IntToStr(d) else
sumStr := SumStr + IntToStr(d);
if Pos <> sr2End then sumStr := sumStr + ', ';
end;//for
sumStr := sumStr + '.';
if Sum > 0 then ShowMessage('Возрастание: ' + ' ' + IntToStr(sum) + #13 + sumStr);
if Sum = 0 then ShowMessage('Стабильность: ' + ' ' + IntToStr(sum) + #13 + sumStr);
if Sum < 0 then ShowMessage('Упадок: ' + ' ' + IntToStr(sum) + #13 + sumStr);
end;//proc
procedure TForm2.Button1Click(Sender: TObject);
begin
MinMax(Input1);
MinMax(Input2);
MinMax(Input3);
end;
end.
Dmk (2015-10-22 20:18:00) [11]>Все равно, выбросить
И так не годится?
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Math;
type
TForm2 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
Input1: array[0..17] of integer = (85,83,81,76,73,82,76,69,62,60,55,50,47,45,34,55,67,88);//Возрастание
Input2: array[0..18] of integer = (85,80,85,90,85,80,85,90,85,80,85,90,85,80,85,90,85,80,85);//Стабильность
Input3: array[0..17] of integer = (85,84,81,80,89,82,76,75,72,80,82,75,74,73,56,50,48,80);//Упадок
sr2: array of integer;
implementation
{$R *.dfm}
procedure MinMax(const AInput: array of integer);
var
A: integer;
B: integer;
Pos: integer;
arrEnd: integer;
sr2End: integer;
sum: integer;
sumStr: string;
d: integer;
InputSize: integer;
begin
Pos := 0;
InputSize := Length(AInput);
arrEnd := (InputSize - 1);
sr2End := arrEnd - 1;
SetLength(sr2, arrEnd);
for Pos := 0 to sr2End do
begin
//Текущий элемент
A := AInput[Pos];
//Следующий элемент
B := AInput[Pos + 1];
//Идет возрастание
if B > A then sr2[Pos] := (B - A);
//Идет убывание
if A > B then sr2[Pos] := (B - A);
end;//for
sum := 0;
for Pos := 0 to sr2End do
begin
d := sr2[Pos];
sum := sum + d;
if d > 0 then
sumStr := SumStr + '+' + IntToStr(d) else
sumStr := SumStr + IntToStr(d);
if Pos <> sr2End then sumStr := sumStr + ', ';
end;
sumStr := sumStr + '.';
if Sum > 0 then ShowMessage('Возрастание: ' + ' ' + IntToStr(sum) + #13 + sumStr);
if Sum = 0 then ShowMessage('Стабильность: ' + ' ' + IntToStr(sum) + #13 + sumStr);
if Sum < 0 then ShowMessage('Упадок: ' + ' ' + IntToStr(sum) + #13 + sumStr);
end;//proc
procedure TForm2.Button1Click(Sender: TObject);
begin
MinMax(Input1);
MinMax(Input2);
MinMax(Input3);
end;
end.
Игорь Шевченко (2015-10-22 18:58:00) [12]
> Это работает.
Все равно, выбросить
Dmk (2015-10-22 16:51:00) [13]Игорь Шевченко © (22.10.15 10:34) [12]
Это работает.
Игорь Шевченко (2015-10-22 10:34:00) [14]Dmk © (22.10.15 09:36) [11]
> только немного доработать надо
Это не надо дорабатывать, это надо выбросить.
Dmk (2015-10-22 09:36:00) [15]Можно так, только немного доработать надо. В начале 2 варианта массивов.
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Math;
type
TForm2 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
Input: array[0..17] of integer = (85,83,81,76,73,82,76,69,62,60,55,50,47,45,34,55,67,88);//Упадок
//Input: array[0..19] of integer = (85,80,85,90,85,80,85,90,85,80,85,90,85,80,85,90,85,80,85,90);//Стабильность
//Input: array[0..17] of integer = (85,86,87,85,89,90,76,85,90,91,92,94,97,79,81,87,90,96);//Возрастание
aMin: array of integer;
aMax: array of integer;
MinLen: integer;
MaxLen: integer;
const
InputSize: integer = Length(Input);
implementation
{$R *.dfm}
procedure MinMax;
var
A: integer;
B: integer;
Pos: integer;
__fall: boolean;
__raise: boolean;
__stability: boolean;
arrSize: integer;
begin
Pos := 0;
arrSize := (InputSize - 1);
__stability := false;
//Считаем первый элемент максимумом
while Pos <= arrSize do
begin
//Текущий элемент
A := Input[Pos];
Inc(MaxLen);
SetLength(aMax, MaxLen);
aMax[MaxLen - 1] := A;
Inc(Pos);
if Pos > arrSize then break;
//Следующий элемент
B := Input[Pos];
//Тенденция стабильна
if B = A then __stability := True;
if __stability then Continue;
//Если на следующем элементе падение
if B < A then
begin
__fall := true;
while __fall do
begin
B := Input[Pos];
Inc(Pos);
if Pos > arrSize then
__fall := false else
__fall := Input[Pos] < B;
end;
//Элемент конца падения
Inc(MinLen);
SetLength(aMin, MinLen);
aMin[MinLen - 1] := B;
end//Падение
else
//Если на следующем элементе возрастание
if B > A then
begin
__raise := true;
while __raise do
begin
B := Input[Pos];
Inc(Pos);
if Pos > arrSize then
__raise := false else
__raise := Input[Pos] > B;
end;
end;//Возрастание
end;//while Pos
end;//proc
procedure TForm2.Button1Click(Sender: TObject);
var
x1, y1: integer;
x2, y2: integer;
TotalLen: integer;
Len: integer;
MinPos, MaxPos: integer;
sr2: array of integer;
Tend: array of integer;
TendSum: integer;
d1, d2: integer;
inv: integer;
gap: integer;
begin
MinMax;
Canvas.Pen.Color := clRed;
Canvas.Pen.Style := psSolid;
Canvas.Pen.Width := 2;
TotalLen := MinLen + MaxLen;
Len := 1;
MaxPos := 0;
MinPos := 0;
while Len <= TotalLen do
begin
SetLength(sr2, Len);
if MinLen <> 0 then
begin
if Odd(Len) then
begin
sr2[Len - 1] := aMax[MaxPos];
Inc(MaxPos);
Inc(Len);
end
else
begin
sr2[Len - 1] := aMin[MinPos];
Inc(MinPos);
Inc(Len);
end;
end else
begin
//Скорее всего стабильность
sr2[Len - 1] := aMax[MaxPos];
Inc(MaxPos);
Inc(Len);
end;
end;
SetLength(Tend, TotalLen - 1);
Len := 0;
while Len <> (TotalLen - 1) do
begin
d1 := sr2[Len];
d2 := sr2[Len + 1];
if d1 = d2 then
begin
Tend[Len] := 0;
Inc(Len);
end
else
begin
if odd(Len) then
Tend[Len] := Max(d1, d2) - Min(d1, d2) else
Tend[Len] := Min(d1, d2) - Max(d1, d2);
Inc(Len);
end;
end;
TendSum := 0;
for Len := 0 to (Length(Tend) - 1) do
begin
TendSum := TendSum + Tend[Len];
end;
if TendSum > 0 then Caption := 'Возрастание';
if TendSum = 0 then Caption := 'Стабильность';
if TendSum < 0 then Caption := 'Упадок';
//Рисуем график
Len := 0;
inv := 200;
gap := 30;
MinPos := 0;
MaxPos := 0;
while Len <= TotalLen do
begin
if MaxPos < MaxLen then
begin
x1 := gap + Len * gap;
y1 := aMax[MaxPos];
if Len = 0 then
begin
if TendSum < 0 then
Canvas.MoveTo(x1, inv - y1) else
Canvas.MoveTo(x1, y1);
end
else
begin
if TendSum < 0 then
Canvas.LineTo(x1, inv - y1) else
Canvas.LineTo(x1, y1);
end;
Inc(MaxPos);
Inc(Len);
if MinPos < MinLen then
begin
x2 := gap + Len * gap;
y2 := aMin[MinPos];
if TendSum < 0 then
Canvas.LineTo(x2, inv - y2) else
Canvas.LineTo(x2, y2);
Inc(MinPos);
end;
end;
Inc(Len);
end;//while
end;
procedure TForm2.FormShow(Sender: TObject);
begin
ClientWidth := 500;
ClientHeight := 300;
end;
end.
Twister (2015-10-20 21:59:00) [16]да вроде не оно
han_malign (2015-10-19 17:23:00) [17]Аппрксимация (линейной) функцией, метод наименьших квадратов???
http://www.cleverstudents.ru/articles/mnk.html
Twister (2015-10-18 08:40:00) [18]Что-то не получается с этой матрицей:
[1]21.00->{0.00}{-1.00}{1.00}{1.00}{5.50}{5.50}{5.50}{5.50}{6.50}{6.50}==36.00
[2]21.00->{0.00}{-1.00}{1.00}{1.00}{5.50}{5.50}{5.50}{5.50}{6.50}{6.50}==36.00
[3]22.00->{1.00}{1.00}{2.00}{2.00}{6.50}{6.50}{6.50}{6.50}{7.50}{7.50}==47.00
[4]20.00->{-1.00}{-1.00}{-2.00}{0.00}{4.50}{4.50}{4.50}{4.50}{5.50}{5.50}==25.00
[5]20.00->{-1.00}{-1.00}{-2.00}{0.00}{4.50}{4.50}{4.50}{4.50}{5.50}{5.50}==25.00
[6]15.50->{-5.50}{-5.50}{-6.50}{-4.50}{-4.50}{0.00}{0.00}{0.00}{1.00}{1.00}==-24.50
[7]15.50->{-5.50}{-5.50}{-6.50}{-4.50}{-4.50}{0.00}{0.00}{0.00}{1.00}{1.00}==-24.50
[8]15.50->{-5.50}{-5.50}{-6.50}{-4.50}{-4.50}{0.00}{0.00}{0.00}{1.00}{1.00}==-24.50
[9]15.50->{-5.50}{-5.50}{-6.50}{-4.50}{-4.50}{0.00}{0.00}{0.00}{1.00}{1.00}==-24.50
[10]14.50->{-6.50}{-6.50}{-7.50}{-5.50}{-5.50}{-1.00}{-1.00}{-1.00}{-1.00}{0.00}==-35.50
[11]14.50->{-6.50}{-6.50}{-7.50}{-5.50}{-5.50}{-1.00}{-1.00}{-1.00}{-1.00}{0.00}==-35.50
Их сумма всегда равна 0
ВладОшин (2015-10-16 09:13:00) [19]если массив
х1
х2
х3
..
добить до матрицы
х1 (x1-x2) (x1-x3) ..
х2 (x2-x1) (x2-x3) ..
х3 (x3-x1) (x3-x1) ..
..
то тенденция от Хn до Хm будет сумма в соотв. строки от n до m
а коэффициент эта сумма на кол-во слагаемых
Token (2015-10-14 11:04:00) [20]Производную найти? Сразу будут видны минимумы, максимумы и скорость.