Calculating Hurst Exponent - delphi

Hi there =) And sorry for my English, in advance
I have a task to calculate hurst exponent by method of linear regression. And I have text description of solution. It looks very easy, but always i get values, that go out from range 0..1. Usually, value is 1.9 or something similar. Sometimes it gets negative value that is close to zero.
I have looked over code about thousand times but couldn't see a mistake.
var
max_z,min_z,x_m:real; //max and min of cumulative sum and mean value of X for every Tau
st,ss,sst,st2 :real;
Al, Herst: real;
x_vr:array of double; //a piece of array with length=tau
i, j, nach: integer;
begin
//file opening and getting values of X array are in another function
nach:=3; //initial value of tau
Setlength(ln_rs,l-nach); //length of ln(R/S) array
Setlength(ln_t,l-nach); //length of ln(tau) array
Setlength(r,l-nach); //length of R array
Setlength(s,l-nach); //length of S array
//Let's start
for tau:=nach to l do //we will change tau
begin
Setlength(x_vr,tau+1); //set new local array (length=tau)
for i:=0 to length(x_vr)-1 do
x_vr[i]:=x[i];
x_m:=Mean(x_vr); //mean value
Setlength(y,tau+1); //length of array of difference from mean value
Setlength(z,tau+1); //length of array of cumulative sum
for i:=0 to tau do
y[i]:=x_vr[i]-x_m; //difference from mean value
z[0]:=y[0];
for i:=1 to tau do //cumulative sum
for j :=i downto 0 do
z[i]:=z[i]+y[j];
max_z:=z[0];
for i:=1 to tau do //max of cumulative sum
max_z:=max(max_z,z[i]);
min_z:=z[0];
for i:=1 to tau do //min of cumulative sum
min_z:=min(min_z,z[i]);
r[tau-nach]:=max_z-min_z; //R value
s[tau-nach]:=0;
for i:=0 to tau do
s[tau-nach]:=power(y[i],2)+s[tau-nach]; //S value
s[tau-nach]:=sqrt(s[tau-nach]/(tau+1));
//new array values
ln_rs[tau-nach]:=Ln(R[tau-nach]/S[tau-nach]); // ln(R/S)
ln_t[tau-nach]:=ln(tau); // ln (tau)
end; //End of calculating
//Method of Least squares
for i:=0 to length(ln_rs)-1 do
st:=st+ln_t[i];
st:=(1/length(ln_rs))*st;
for i:=0 to length(ln_rs)-1 do
ss:=ss+ln_rs[i];
ss:=(1/length(ln_rs))*ss;
for i:=0 to length(ln_rs)-1 do
sst:=sst+ln_t[i]*ln_rs[i];
sst:=(1/length(ln_rs))*sst;
for i:=0 to length(ln_rs)-1 do
st2:=st2+ln_t[i]*ln_t[i];
st2:=(1/length(ln_rs))*st2;
Herst:=(sst-st*ss)/(st2-st*st); //coefficient of approximal function
al:=ss-st*Herst;
Thanks everybody =)
P.S.
for tau:=nach to l do
There is L, not 1. And L is Length of X array. And L>nach always besides last step, when l=nach.
P.P.S.
It works, guys. But values are not right. And they go out from range. Maybe, there is mistake in algorithm. Or maybe I skiped some step.
Last Update
It's mystic, but i only changed method of calculating array Z and it started works correctly....
Thanks all =)

First thing I see:
nach := 3;
for tau := nach to l do //w
This counts up. And because nach>1, the body of this loop won't be executed.
If you expect to count down. Use the downto variant. To count down:
for tau := nach downto l do //w

Given that the main loop (for tau) iterates from nach to l, the first four SetLength calls should set the length of l - nach + 1 instead of l - nach.

Should the line
z[i]:=z[i]+y[j];
not be
z[i]:=z[i - 1]+y[j];
?

Related

How to convert Delphi TDateTime to String with microsecond precision

I need to convert a TDateTime to a String with microsecond precision.
In case of millisecond precision it is possible to use formatting:
DateTimeToString(Result, 'd.m.yyyy hh:nn:ss.zzz', dateTime);
but I need three more digits (microseconds).
It is possible to take the fractional part and divide it by 1/86400/1000000 but I'm looking for more efficient way to convert it.
The accuracy of a date-time varies depending how far away from "zero" you are.
A Delphi TDateTime is actually an 8-byte floating point Double, with zero being 12/30/1899 12:00:00 am.
We can figure out the precision of a TDateTime by incrementing the floating point datetime by the smallest quantum possible:
function AddQuantumToDateTime(const dt: TDateTime): TDateTime;
var
overlay: Int64 absolute Result;
begin
Result := dt;
overlay := overlay+1;
end;
With this, we can figure out the smallest increment that a TDateTime can even handle. It varies with the date being used, as the further you are from zero, the larger the quantum amount is:
12/31/1899: ±0 ns
1/1/1900: ±0 ns
1/1/1970: ±314 ns
1/1/2000: ±629 ns
1/1/2016: ±629 ns
1/1/2038: ±629 ns
1/1/3000: ±5,029 ns
1/1/4000: ±10,058 ns
1/1/5000: ±20,117 ns
1/1/6000: ±20,117 ns
1/1/7000: ±20,117 ns
1/1/8000: ±40,233 ns
1/1/9000: ±40,233 ns
1/1/9999: ±40,233 ns
So for the time being, a DateTime can give you a resolution of about half a microsecond.
While the Windows FILETIME structure does support a resolution of 100ns, the SYSTEMTIME structure only supports down to the millisecond:
typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME;
Microsoft SQL Server's new datetime2(7) returns datetime strings with up to seven digit (100 ns) of fractional second accuracy:
SELECT CAST('20160802' AS datetime2(6)) AS TheNow
TheNow
==========================
2016-08-02 00:00:00.000000
Your question then is how to convert a TDateTime to a string that contains microsecond (billionths of a second) precision. You already have your answer:
function DateTimeToStrUs(dt: TDatetime): string;
var
us: string;
begin
//Spit out most of the result: '20160802 11:34:36.'
Result := FormatDateTime('yyyymmdd hh":"nn":"ss"."', dt);
//extract the number of microseconds
dt := Frac(dt); //fractional part of day
dt := dt * 24*60*60; //number of seconds in that day
us := IntToStr(Round(Frac(dt)*1000000));
//Add the us integer to the end:
// '20160801 11:34:36.' + '00' + '123456'
Result := Result + StringOfChar('0', 6-Length(us)) + us;
end;
Where:
DateTimeToStrUs(Now)
Returns:
20160802 11:34:36.482364

Delphi FormatFloat

I have an output txtfile with some float numbers and I like to print in different formats, y try with:
FormatFloat('00000;000.0;00.00', val)
FormatFloat('00.00;000.0;00000', val)
But I take wrong outputs. What I need is:
If val < 10 then output like '00.00'
If 10 < val < 100 then output like '000.0'
If val > 100 then output like '00000'
It's a huge amount of float values, so, I need a low processing solution and I think more conditionals will slow down the application. ¿Any advice?
Thank you
Using conditional tests to sort the values into separate outputs is not going to affect performance in a significant way. The format process is far more elaborate. One important thing about optimization is to only walk that path if you can measure a performance hit in the actual code.
if (val < 10) then
s := FormatFloat('00.00',val)
else
if (val < 100) then
s := FormatFloat('000.0',val)
else
s := FormatFloat('00000',val);
Also consider using the thread-safe FormatFloat with a supplied FormatSettings variable.
I suppose that conditionals would work faster, but consider this sketch (care about out-of-range values):
const
FormatString: array[-1..2] of string = ('0.000', '0.00', '0.0', '0');
var
x: Double;
i: integer;
begin
x := 0.314;
for i := 1 to 4 do begin
Memo1.Lines.Add(FormatFloat(FormatString[Floor(Log10(x))], x));
x := x * 10;
end;
0.314
3.14
31.4
314

Generate random number in a float range

How we can generate randomize number between a range in the Float numbers (in delphi xe3) ?
For example, randomize number between [0.10 to 0.90].
I need give results like:
[ 0.20 , 0.32 , 0.10 , 0.50 ]
Thanks for solutions....
Another option is to use RandomRange (returns: AFrom <= r < ATo) as follow:
RandomRange(10, 90 + 1) / 100
or
RandomRange(10, 90 + 1) * 0.01
will return numbers in the range of 0.10 to 0.90 (including 0.90)
var
float : Double;
float := Random; // Random float in range: 0 <= float < 1
float := 0.1 + float*0.8 // 0.1 <= float < 0.9
To initialize the Random number generator, make a single call to Randomizeor set the RandSeed parameter before calling the Random function for the first time.
Not doing so, generates the same sequence every time you run the program. Note however, that this sequence is not guaranteed when recompiling for another compiler version.
Try this:
function RandomRangeF(min, max: single): single;
begin
result := min + Random * (max - min);
end;
This is a bit cheeky but here goes: Depends how many numbers you want after the floating point. For example, if you want 1 number, you could generate in the 100 - 999 range and then divide by 10. Or 1000 - 9999 and divide by 100.

How to get number webcams, with using OpenCV

I get number webcams with using this code:
CountCamers := 0;
j := 0;
capture := cvCreateCameraCapture(700);
while Assigned(capture) do
begin
inc(CountCamers);
cvReleaseCapture(#capture);
capture := nil;
inc(j);
capture := cvCreateCameraCapture(700 + j);
end;
But, sometimes this code give at result number webcams equal 100 (max number camera of domain), but in reality only one webcam is connected. How to get number webcams? Thanks in advance.
When there is only 1 camera, the index is unused (you can pass -1).
Try instead to check the identity of the opaque struct pointer returned. I think (sorry, not tested because I have just 1 camera attached) that should be unique for each device.
You can to get number of webcams checking if you can to get a Frame. Example in python:
def get_num_cameras():
n = 0
num_cameras = 0
while n < 100:
camera = CaptureFromCAM(n)
if QueryFrame(camera):
num_cameras += 1
n += 1
return num_cameras

Using Length() with multi-dimensional dynamic arrays in Delphi

I am using a multi-dimensional dynamic array in delphi and am trying to figure this out:
I have 2 seperate values for the first index and second index that are totally seperate of each other.
As new values come I want to grow the array if that new value is outside of either bound.
For new values x, y
I check:
if Length(List) < (x + 1) then
SetLength(List, x + 1);
if Length(List[0]) < (y + 1) then
SetLength(List, Length(List), y + 1);
Is this the correct way to do this or is there a better way to grow the array as needed?
It looks fine to me - if you change the last line to
SetLength(List, Length(List), y + 1);
I think you forgot to use the second index on the second dimension;
Your code should probably read like this :
if Length(List) < (x + 1) then
SetLength(List, x + 1);
if Length(List[x]) < (y + 1) then
SetLength(List[x], y + 1);
Note the use of 'x' as the first dimension index when growing the second dimension.
One caution though :
You should be aware of the fact that Delphi uses reference-counting on dynamic arrays too (just like how it's done with AnsiString).
Because of this, growing the array like above will work, but any other reference to it will still have the old copy of it!
The only way around this, is keeping track of these array's with one extra level of indirection - ie. : Use a pointer to the dynamic array (which is also a pointer in itself, but that's okay).
Also note that any of those 'external' pointers should be updated in any situation that the address of the dynamic array could change, as when growing/shrinking it using SetLength().
#PatrickvL:
Sorry, but that is just plain wrong. Your code does not even compile because it tries to set two dimensions for the single-dimensional element List[x]. (PatrickvL updated his code so this part of the answer is no longer valid.)
The following code demonstrates multidimensional array resizing.
program TestDimensions;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
List: array of array of integer;
begin
//set both dimensions
SetLength(List, 3, 2);
Writeln('X = ', Length(List), ', Y = ', Length(List[0])); //X = 3, Y = 2
//set main dimension to 4, keep subdimension untouched
SetLength(List, 4);
Writeln('X = ', Length(List), ', Y = ', Length(List[0])); //X = 4, Y = 2
//set subdimension to 3, keep main dimenstion untouched
SetLength(List, Length(List), 3);
Writeln('X = ', Length(List), ', Y = ', Length(List[0])); //X = 4, Y = 3
//all List[0]..List[3] have 3 elements
Writeln(Length(List[0]), Length(List[1]), Length(List[2]), Length(List[3])); //3333
//you can change subdimension for each List[] vector
SetLength(List[0], 1);
SetLength(List[3], 7);
//List is now a ragged array
Writeln(Length(List[0]), Length(List[1]), Length(List[2]), Length(List[3])); //1337
//this does not even compile because it tries to set dimension that does not exist!
// SetLength(List[0], Length(List[0]), 12);
Readln;
end.
The Delphi help also explains this quite nicely (Structured Types, Arrays).
Multidimensional Dynamic Arrays
To declare multidimensional dynamic arrays, use iterated array of ... constructions. For example,
type TMessageGrid = array of array of string;
var Msgs: TMessageGrid;
declares a two-dimensional array of strings. To instantiate this array, call SetLength with two integer arguments. For example, if I
and J are integer-valued variables,
SetLength(Msgs,I,J);
allocates an I-by-J array, and Msgs[0,0] denotes an element of that array.
You can create multidimensional dynamic arrays that are not rectangular. The first step is to call SetLength, passing it parameters for the first n dimensions of the array. For example,
var Ints: array of array of Integer;
SetLength(Ints,10);
allocates ten rows for Ints but no columns. Later, you can allocate the columns one at a time (giving them different lengths); for example
SetLength(Ints[2], 5);
makes the third column of Ints five integers long. At this point (even if the other columns haven't been allocated) you can assign values to the third column - for example, Ints[2,4] := 6.
The following example uses dynamic arrays (and the IntToStr function declared in the SysUtils unit) to create a triangular matrix of strings.
var
A : array of array of string;
I, J : Integer;
begin
SetLength(A, 10);
for I := Low(A) to High(A) do
begin
SetLength(A[I], I);
for J := Low(A[I]) to High(A[I]) do
A[I,J] := IntToStr(I) + ',' + IntToStr(J) + ' ';
end;
end;

Resources