Mathlib v2

AdministratorAdministrator Member, Moderator, Administrator Posts: 2,500
edited 2008-03-15 in Download section
Mathlib
With this Codeunit 50005 (change No. to wathever you want) you can calculate following Functions insinde Navision without any external ocx or tool. The Unit works standalone and need no other Objects, references or Tablechanges in Navision.
There is no special command from 3.70, so you can convert it to any Navision (even 3.56/blue) version you like.

!
Sin
Cos
Tan
ArcSin
ArcCos
Log
Ln
Adjust
Grad>Rad
Deg>Rad
Rad>Deg
Sqrt
gcd
lcm
Prime
CrossFoot
(a+b)²
(a-b)²
(a+b)*(a-b)
Pi
E
Euler
Sign
Max
Min
Int
EuklDistance
ManhDistance
StreetDistance
ConvLongtitute2Km
ConvLatitude2Km

http://www.mibuso.com/dlinfo.asp?FileID=745

Discuss this download here.

Comments

  • rthswrthsw Member Posts: 73
    Please change the 12 in SIN to 11. Only Odd in this Taylorrow.
  • Arjan_SomersArjan_Somers Member Posts: 64
    Nice Job!
    Really missed the mathematical functions!

    But since ArcSin and ArcCos depend on the (unimplemented) ArcTan,
    I re-implemented those 2.

    ArcCos:
    parameter a (decimal)
    variable x (decimal)
    
    x := a;
    REPEAT
      x := x - (Cos(x)-a)/(-Sin(x));
    UNTIL (ABS(Cos(x)-a) <= 0.00000001);
    EXIT(x);
    

    ArcSin:
    parameter a (decimal)
    variable x (decimal)
    
    x := a;
    REPEAT 
      x := x - (Sin(x)-a)/Cos(x)
    UNTIL (ABS(Sin(x)-a) <= 0.00000001);
    EXIT(x);
    

    It's quite accurate, but not too fast. (to change the balance between accuracy and speed you could change 0.00000001 to a bigger value for more speed

    Enjoy!
  • Arjan_SomersArjan_Somers Member Posts: 64
    edited 2006-07-20
    Hey all!

    I made another improvement.

    The sine function gave rounding errors when near the 90 degrees.
    This is because small amount of terms in the taylor series.
    That's why i added some to improve accuracy, but this greatly reduced the calculation speed.

    That why i used Horner's rule to simplify the calculation

    the new code is:
    For the SIN function
    x := Adjust(x);
    EXIT(x*(1 - (x*x)*(1 - (x*x)*(1 - (x*x)*(1 - (x*x)*(1 - (x*x)*(1 - (x*x)*(1 - (x*x)*(1 - (x*x)
    /(16*17) )/(14*15) )/(12*13) )/(10*11) )/(8*9) )/(6*7) ) / (4*5) ) /(2*3) ));
    

    and for COS: (just a phase difference (This way if you adjust the precision for sin, it also changes for Cos.
    EXIT(Sin(x-PI/2));
    

    It's much mor accurate, and still faster!

    Enjoy
  • Marije_BrummelMarije_Brummel Member, Moderators Design Patterns Posts: 4,262
  • sirpetesirpete Member Posts: 15
    What do the StreetDistance and ConvLatitude2Km functions do? Is street distance the actual distance between 2 locations (ie: mapquest distance)?

    We did a scheduling report that calculated distances from 2 locations based on zip codes, but the actual street ditance is only estimated (straight line distance from Lat/Long to Lat2/Long2 + 20% (or 30%, can't remember which one we used).

    Peter
  • rthswrthsw Member Posts: 73
    ConvertLatitute2KM converts a Earthangel into Kilometers from 0°. Because this distance differs (on Equatorial ~ 70Km to Polar ~0Km) you need to submit the Longtitute. The Distance between 2 Longtitudes are Fix.

    With the StreetDist you aproximate the Street Distance between 2 Coordinates (in Kilometer). We use this function exactly for the same as you do, and find on this way for example every customer with a distance between 0 and 40 Km from Our Hometown).
  • Arjan_SomersArjan_Somers Member Posts: 64
    rthsw kindly pointed me at some errors in my code. They where small typing errors, but it resulted in completely wrong computations. So if you already copied this code, copy it again please.
  • Arjan_SomersArjan_Somers Member Posts: 64
    Since i am on a code snppet streak here, i might as well post another one :D

    Just as rthsw i made some distance calculations.
    I also made a quite precise distance calculation.
    It computes distances in km between 2 geocoordinates. Taking in account the shape of the earth and the distibution of the coordinates.

    This means that takes in account that one degree at the equator is longer in km's that say in the netherlands, or even more at the poles.
    It als take in account that the earth is a sphere and not a flat plane. So it calculates a straight line across the sphere, instead of just a straight line.

    Of course this is much slower that the currently present calculations, but it gives nice results.

    Hope you like this one!
    //returns the distance between 2 geocoördinates
    ldecTheta := pdecLong2 - pdecLong1;
    rdecDistance := Math.Sin(Math."Deg>Rad"(pdecLat1)) * Math.Sin(Math."Deg>Rad"(pdecLat2))
                  + Math.Cos(Math."Deg>Rad"(pdecLat1)) * Math.Cos(Math."Deg>Rad"(pdecLat2))
                  * Math.Cos(Math."Deg>Rad"(ldecTheta));
    rdecDistance := Math.ArcCos(rdecDistance);
    rdecDistance := ABS(rdecDistance) * 6372.79787; // 1 rad difference  is on earth about 6372,79787 KM
                                                    // (Mean Circumference Earth) / 2*PI = 40'041,47 / 6,28... = 6372,7978791658343303296861445676
    
  • sirpetesirpete Member Posts: 15
    Has anyone had any luck getting accurate street distances rather than estimates? For instance, using Lat/Long or ZIP codes to query MapQuest or a similar website (or MS MapPoint perhaps - I recall seeing some MapPoint integration for Navision in Mibuso before). With out estimated travel distances we find that it could still range widely compared to actual street distances.

    Peter
  • Marije_BrummelMarije_Brummel Member, Moderators Design Patterns Posts: 4,262
    You can use the mappoint on the download section.

    You can also integrate with Map & Guide, but this is quite an expensive product.
  • AdministratorAdministrator Member, Moderator, Administrator Posts: 2,500
    Mathlib v2
    Single Codeunit without any SideEfect with some Mathematic Functions normaly not avaible in Fin. Improvements (as usable) from Forum and now with arctan! Textfile for implementation in any Navisionversion (even DOS) or Turbopascal Program for educational purposes.

    !
    Sin
    Cos
    Tan
    ArcSin
    ArcCos
    ArcTan
    Log
    Ln
    CalcLog
    Adjust
    Grad>Rad
    Deg>Rad
    Rad>Deg
    Sqrt
    gcd
    lcm
    Prime
    CrossFoot
    (a+b)²
    (a-b)²
    (a+b)*(a-b)
    Pi
    E
    Euler
    Sign
    Max
    Min
    Int
    EuklDistance
    ManhDistance
    StreetDistance
    ConvLongtitute2Km
    ConvLatitude2Km

    http://www.mibuso.com/dlinfo.asp?FileID=745

    Discuss this download here.
  • Arjan_SomersArjan_Somers Member Posts: 64
    edited 2007-07-27
    ...
  • Arjan_SomersArjan_Somers Member Posts: 64
    Anyways,

    1. You should add ABS to the sqrt function, or calling ArcCos will generate an error sometimes, because x can get values like -0.0000002341.

    2. Great Job on implementing arcTan, but the loop is kindda long and thus kindda slow, so you could considering using my ArcCos and ArcSin function, also because my function have a higher precision.
  • Marije_BrummelMarije_Brummel Member, Moderators Design Patterns Posts: 4,262
    Well, I must admit that when I first read this post I figured, who needs it!

    But today I have added the Exp funtion and succesfully converted Mercatorcordinates to Geodecimal. :mrgreen:
    Exp(x : Decimal) : Decimal
    EXIT(POWER(E, x));
    
  • rkaufmannrkaufmann Member Posts: 71
    Just downloaded the Mathlib v2 and by looking thru the code I found the parser functions. These are not working yet, right?
  • John3John3 Member Posts: 16
    When i calculate the sin of 50 for example I get the result of 193.003.111.963.430,642 in stead of -0,262374854 (excel).

    What am I doing wrong ?

    Thanks for helping !
  • Arjan_SomersArjan_Somers Member Posts: 64
    I just tried the following code:
    MESSAGE(Format(Math.Sin(50)));
    

    And it gives the answer:
    -0,262374854 
    

    So it seems the code is correct, i don't have a clue as why it's not working for you. :-k
  • radek.bbradek.bb Member Posts: 49
    IF x = 1 THEN //Log(1) = 1;
            EXIT(1);
    
    Really :D:D:D
Sign In or Register to comment.