### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Lmath ulogifit samples  (Read 1775 times)

#### wp

• Hero Member
• Posts: 7752
##### Re: Lmath ulogifit samples
« Reply #15 on: September 23, 2020, 11:44:00 am »
Just an idea: The attached program introduces a TVector as a separate type (not a renamed "array of float"), so that the standard functions Length() and Low(), as well as the math functions Mean(), Sum() etc can no longer be applied. Using an additional (optional) parameter in DimVector the user can decide whether he wants 0 or 1 as the first index. Using {\$mode Delphi} or {\$mode objfpc} along with {\$modeswitch advancedrecords} this new type could be made to behave like a simple array to the outside.

Code: Pascal  [Select][+][-]
1. program Project1;
2.
3. {\$mode Delphi}
4.
5. uses
6.   SysUtils;
7.
8. type
9.   float = double;
10.
11.   TVector = record
12.   private
13.     FValues: Array of Float;
14.     FOneBased: Boolean;
15.     function GetValue(AIndex: Integer): Float; inline;
16.     procedure SetValue(AIndex: Integer; AValue: Float); inline;
17.   public
18.     property Value[AIndex: Integer]: Float read GetValue write SetValue; default;
19.     property OneBased: boolean read FOneBased;
20.   end;
21.
22.   function TVector.GetValue(AIndex: Integer): Float;
23.   begin
24.     if FOneBased then dec(AIndex);
25.     Result := FValues[AIndex];
26.   end;
27.
28.   procedure TVector.SetValue(AIndex: Integer; AValue: Float);
29.   begin
30.     if FOneBased then dec(AIndex);
31.     FValues[AIndex] := AValue;
32.   end;
33.
34. procedure DimVector(var V: TVector; ADim: Integer; IsOneBased: Boolean = true);
35. begin
36.   V.FOneBased := IsOneBased;
38. end;
39.
40. function Dim(V: TVector): Integer;
41. begin
42.   Result := Length(V.FValues);
43. end;
44.
45. var
46.   v: TVector;
47.   i: Integer;
48.
49. begin
50.   DimVector(v, 5, false);  // Create a 0-based 5-dim vector
51.   v[0] := 1.0;
52.   v[1] := 2.0;
53.   v[2] := 3.0;
54.   v[3] := 4.0;
55.   v[4] := 5.0;
56.   WriteLn('0-based vector');
57.   for i := 0 to Dim(V)-1 do
58.     WriteLn('v[',i,']=',v[i]:0:3);
59.
60.   WriteLn;
61.
62.   DimVector(v, 5);  // Create a 1-based 5-dim vector
63.   v[1] := 1.0;
64.   v[2] := 2.0;
65.   v[3] := 3.0;
66.   v[4] := 4.0;
67.   v[5] := 5.0;
68.   WriteLn('1-based vector');
69.   for i := 1 to  Dim(V) do
70.     WriteLn('v[',i,']=', v[i]:0:3);
71.
72.   // Access element at index 0 --> RunError(201) when range and overflow checking are active
73.   WriteLn('v[0]=',v[0]);
74.
76. end.

I am not claiming this to be the ultimate solution; it could be a bit slower than the current one with dynamic array because of the frequent addition/subtraction of 1 in case of the 1-based case. As I said: just an idea...
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

#### glorfin

• Full Member
• Posts: 109
##### Re: Lmath ulogifit samples
« Reply #16 on: September 23, 2020, 12:17:51 pm »
> TVector as a separate type
Something in direction of TPoints in lmPointsVec from lmComponents?

#### erik2727

• New Member
• Posts: 14
##### Re: Lmath ulogifit samples
« Reply #17 on: September 23, 2020, 12:41:27 pm »
hi,

Agreed , refer to manual when in doubt , got stuck , shout for help in forum . No point reinvent the wheel when everything is working orderly!
« Last Edit: September 23, 2020, 12:43:07 pm by erik2727 »

#### wp

• Hero Member
• Posts: 7752
##### Re: Lmath ulogifit samples
« Reply #18 on: September 23, 2020, 01:10:11 pm »
> TVector as a separate type
Something in direction of TPoints in lmPointsVec from lmComponents?
Yes, similar. But "my" TVector is a record (no class like TPoints) and, therefore, there is no explicit need for destruction.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

#### erik2727

• New Member
• Posts: 14
##### Re: Lmath ulogifit samples
« Reply #19 on: September 23, 2020, 01:40:57 pm »
Hi,

Put this up for future feature request or enhancement, I am ok as long as no performance degrade or issues

« Last Edit: September 23, 2020, 01:42:54 pm by erik2727 »

#### glorfin

• Full Member
• Posts: 109
##### Re: Lmath ulogifit samples
« Reply #20 on: September 23, 2020, 05:43:22 pm »
> TVector as a separate type
Something in direction of TPoints in lmPointsVec from lmComponents?
Yes, similar. But "my" TVector is a record (no class like TPoints) and, therefore, there is no explicit need for destruction.
I thought about it. In fact, I have, for my own needs, similar class called TReals, but problem here is that call to GetValue/SetValue each time one wants to assign/read value of an array is very inefficient. If you noticed,  variable Points in TPoints is public to get direct access to array elements. Inlining function would make it somewhat faster, but still, there is additional comparison and additional assignment.

#### wp

• Hero Member
• Posts: 7752
##### Re: Lmath ulogifit samples
« Reply #21 on: September 24, 2020, 01:14:49 pm »
@glorfin: Re-thinking "my" TVector in reply #15 again, I see that it may open another box of Pandora since the same type TVector can be both one-based as well as zero-based. Assume v0 is a zero-based and v1 a 1-based TVector. What if the users tries to calculate their sum, v0 + v1? Will he add (v0[0]+v1[1], v0[1]+v1[2], ...)? Not very logical -- it is a bad idea to allow for both worlds.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

#### erik2727

• New Member
• Posts: 14
##### Re: Lmath ulogifit samples
« Reply #22 on: September 24, 2020, 01:32:08 pm »
Hi,

In my view, the whole Tvector structure to store data may have been  restricted by Pascal bounded fixed array concept, it would be good to borrow c++ vector design to auto increase the capacity as needed.

I have come across few c++ math numerial library having the same issues simply because the data are bind to array, the one that offer flexibility and satisfy my need is boost c++ ode where data both input and output are stored in vector<any> format as i dealt with ode45 and numerical advanced calculus in my research.

This is just an expression of opinion, not requesting any major modification to existing Tvector concepts as I know is a dangerous and daunting task to redesign existing library
« Last Edit: September 24, 2020, 01:46:15 pm by erik2727 »

#### glorfin

• Full Member
• Posts: 109
##### Re: Lmath ulogifit samples
« Reply #23 on: September 24, 2020, 02:41:52 pm »
@erik2727
Free Pascal dynamic arrays (including TVector) can be resized with SetLength(). Moreover, there are Insert() and Delete() procedures which insert or delete elements and resize arrays accordingly. However, I do not like an idea that an array must be completely reallocated at each insert/delete. LMath has a unit uVectorHelper, where Insert and Delete do not change length, but in Insert last value is lost, and in Delete last value is set to "0".

#### erik2727

• New Member
• Posts: 14
##### Re: Lmath ulogifit samples
« Reply #24 on: September 24, 2020, 03:25:10 pm »
hi,

By virtue of the fact that  TVector is indeed an  dynamic array  , would calling DimVector at anytime   resize an allocated array or not as Lmath manual  only briefly state below  quoted statement

Sorry I don't quite understand what vector meant in free  pascal dialect ,is it a record or container type ? I also look into free pascal Numlib vector declaration

LMath

Vector  type      Matrix type    Base variable
TVector               TMatrix       Floating point number (type Float)

Creates a vector V[0..Ub] based on a type corresponding to a parameter
(Float, Integer, Complex, RealPoint, Boolean; Strings. In DMath, procedures

NumLib

Vectors

NumLib often passes vectors to procedures as one ArbFloat plus some integer value. This ArbFloat value is the first value of an array containing the vector, the integer is the count of elements used from this array. Internally an array type is mapped over the first value in order to access the other array elements. This way both 0- and 1-based arrays as well as static and dynamic arrays can be passed to the functions and procedures of NumLib.
« Last Edit: September 24, 2020, 03:48:55 pm by erik2727 »

#### glorfin

• Full Member
• Posts: 109
##### Re: Lmath ulogifit samples
« Reply #25 on: September 24, 2020, 06:45:03 pm »
@erik2727:
In principle, vector is just one-dimentional array. In Pascal there are static and dynamic arrays:
https://www.freepascal.org/docs-html/ref/refsu14.html

Importantly, static array may be declated with any indexing you want:
Code: Pascal  [Select][+][-]
1. type
2.   TFortranArray = array[1..122] of float;
3.   TColors = (Red,Green,Blue);
4.   TColorArray = array[TColors] of byte;
5.
but dynamic arrays are always 0-based.
In LMath,
Code: Pascal  [Select][+][-]
1. TVector = array of Float;
2. TCompVector = array of Complex;
3.
etc.
So, all T*Vector types in LMath are dynamic arrays, internally 0-based. When fortran-style functions of LMath use "1-based" arrays, they simply ignore first element, with index "0".
Call to system function SetLength(V,10) allocates dynamic array with 10 elements, indexed  from V[0] to V[9]. If we think "fortran-style", we would expect highest index 10. Therefore, LMath defines own wrapper function DimVector, where not length, but highest index of an array is passed: DimVector(V,10) allocates V[0] to V[10].

And yes, DimVector and SetLength resize an allocated array and copy all existing values into new array, of cource truncating if needed.

#### nanobit

• Jr. Member
• Posts: 93
##### Re: Lmath ulogifit samples
« Reply #26 on: September 24, 2020, 07:25:55 pm »