Page 1 of 1

### Math Functions

Posted: 20 Aug 2018, 15:49
Hello!
I would like the following functions to be added: Map, ATan2, Radians (degrees to radians), Degrees (radians to degrees), Factorial, Log(x,base=10), Hypot, ACosh, ASinh, ATanh, Cosh, Sinh, Tanh.
Constants: PI (also PI2?), E (_E?).

Here is an example using the Map function (AHKv1).
Original here: https://autohotkey.com/boards/viewtopic ... 20#p102945.

Code: Select all

``````#NoEnv
#Warn All, Off
#SingleInstance Force
SetBatchLines -1

; ===============================================================================================================================

global w   := 800
global h   := 600
global a   := 0
global b   := 0
global hue := 0

; ===============================================================================================================================

hSHLWAPI := DllCall("LoadLibrary", "Str", "shlwapi.dll", "Ptr")
hGDIPLUS := DllCall("LoadLibrary", "Str", "GdiPlus.dll", "Ptr")
VarSetCapacity(SI, 24, 0), Numput(1, SI, 0, "Int")
DllCall("GdiPlus.dll\GdiplusStartup", "UPtr*", pToken, "Ptr", &SI, "Ptr", 0)

; ===============================================================================================================================

Gui, +LastFound +hwndhGDIPFun
Gui, Show, w%w% h%h%

DllCall("GdiPlus.dll\GdipCreateFromHWND", "Ptr", hGDIPFun, "Ptr*", pGraphics)
DllCall("GdiPlus.dll\GdipCreateBitmapFromGraphics", "Int", w, "Int", h, "Ptr", pGraphics, "Ptr*", pBitmap)
DllCall("Gdiplus.dll\GdipGetImageGraphicsContext", "Ptr", pBitmap, "Ptr*", pGraphicsCtxt)
DllCall("Gdiplus.dll\GdipSetSmoothingMode", "Ptr", pGraphicsCtxt, "Int", 2)
DllCall("Gdiplus.dll\GdipCreatePen1", "UInt", 0xFFFFFFFF, "Float", 1, "Int", 2, "Ptr*", pPen)
DllCall("GdiPlus.dll\GdipGraphicsClear", "Ptr", pGraphicsCtxt, "UInt", 0x7F000000)

loop
{
DllCall("GdiPlus.dll\GdipSetPenColor", "Ptr", pPen, "UInt", "0xCC" ColorHLSToRGB(hue, 120, 240))
, X0 := map( sin(a)    , -1, 1, W/5, W - W/5 )
, Y0 := map( cos(a)*1.5, -1, 1, H/5, H - H/5 )
, X1 := map( sin(b)    , -1, 1, W/5, W - W/5 )
, Y1 := map( cos(b)    , -1, 1, H/5, H - H/5 )
, DllCall("GdiPlus.dll\GdipDrawLine", "ptr", pGraphicsCtxt, "ptr", pPen, "float", x0, "float", y0, "float", x1, "float", y1)
, a += 0.04, b += 0.05, hue += 1, hue := (hue > 239) ? mod(hue, 239) : hue
, DllCall("Gdiplus.dll\GdipDrawImage", "Ptr", pGraphics, "Ptr", pBitmap, "Float", 0, "Float", 0)
} until (a > 24)
return

; ===============================================================================================================================

ColorHLSToRGB(hue, lum, sat)
{
clr := DllCall("shlwapi.dll\ColorHLSToRGB", "UShort", hue, "UShort", lum, "UShort", sat)
return Format("{:06X}", ((clr & 0xff00) | ((clr & 0xff) << 16) | ((clr & 0xff0000) >> 16)))
}

Map(Value, Start1, Stop1, Start2, Stop2, ConstrainMin := FALSE, ConstrainMax := FALSE)
{
return ( ConstrainMin && Value < Start1 ) ? Start2 : ( ConstrainMax && Value > Stop1 ) ? Stop2
: ( ( ( Value - Start1 ) / (Stop1 - Start1) ) * ( Stop2 - Start2 ) ) + Start2
}

; ===============================================================================================================================

GuiClose:
GuiEscape:
DllCall("GdiPlus.dll\GdipDeletePen", "Ptr", pPen)
DllCall("GdiPlus.dll\GdipDeleteGraphics", "Ptr", pGraphicsCtxt)
DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr", pBitmap)
DllCall("GdiPlus.dll\GdipDeleteGraphics", "Ptr", pGraphics)
DllCall("GdiPlus.dll\GdiplusShutdown", "Ptr", pToken)
DllCall("FreeLibrary", "Ptr", hGDIPLUS)
DllCall("FreeLibrary", "Ptr", hSHLWAPI)
ExitApp
return``````
I consider that these are the basic functions (and constants) that we should have built-in.
These functions are very useful when working with graphics (eg. gdip) and performance is important.

### Re: Math Functions

Posted: 21 Aug 2018, 15:25
map() is a common name for a functional programming feature of applying a function to a range of values.

Code: Select all

``````arr := [1,2,3]
arr2 := map(arr, "square")
msgbox, % arr2.1 "`n" arr2.2 "`n" arr2.3
return

square(x)
{
return (x*x)
}

map(array, function)
{
if (function.name == "")
function := Func(function)
returnarray := []
for i,v in array
returnarray[i] := function.call(v)
return returnarray
}
``````
not sure what your map() func does but i'd recommend Naming it something different

### Re: Math Functions

Posted: 21 Aug 2018, 18:05
@guest3456 You're right, it should have a different name.
not sure what your map() func does: 1 ⠀⠀⠀2.
Another example:

Code: Select all

``````#NoEnv
#Warn All, Off
#SingleInstance Force
SetBatchLines -1
CoordMode Mouse, Client

hGDIPLUS := DllCall("LoadLibrary", "Str", "Gdiplus.dll", "Ptr")
VarSetCapacity(SI, 24, 0), Numput(1, SI, 0, "Int")
DllCall("Gdiplus.dll\GdiplusStartup", "UPtr*", pToken, "Ptr", &SI, "Ptr", 0)
w := 640, h := 360
Gui +LastFound +hwndhGui
Gui Show, w%w% h%h%

DllCall("GdiPlus.dll\GdipCreateFromHWND", "Ptr", hGui, "Ptr*", pGraphics)
DllCall("GdiPlus.dll\GdipCreateBitmapFromGraphics", "Int", w, "Int", h, "Ptr", pGraphics, "Ptr*", pBitmap)
DllCall("Gdiplus.dll\GdipGetImageGraphicsContext", "Ptr", pBitmap, "Ptr*", pGraphicsCtxt)
DllCall("Gdiplus.dll\GdipSetSmoothingMode", "Ptr", pGraphicsCtxt, "Int", 2)
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0, "UPtrP", pBrush, "UInt")
DllCall("GdiPlus.dll\GdipGraphicsClear", "Ptr", pGraphicsCtxt, "UInt", 0x7F000000)

loop
{
MouseGetPos X, Y
d := map(X, 0, W, 0, 250), c := (0xFF << 24) | (0xFF << 16) | (map(X, 0, W, 0, 175) << 8) | 0
DllCall("Gdiplus.dll\GdipGraphicsClear", "Ptr", pGraphicsCtxt, "UInt", 0xFF000000)
DllCall("Gdiplus.dll\GdipSetSolidFillColor", "UPtr", pBrush, "UInt", c, "UInt")
FillStar(pGraphicsCtxt, pBrush, W/2, H/2, d/2, d)
DllCall("Gdiplus.dll\GdipDrawImage", "Ptr", pGraphics, "Ptr", pBitmap, "Float", 0, "Float", 0)
}
return

Map(Value, Start1, Stop1, Start2, Stop2, ConstrainMin := FALSE, ConstrainMax := FALSE)
{
return ( ConstrainMin && Value < Start1 ) ? Start2 : ( ConstrainMax && Value > Stop1 ) ? Stop2
: ( ( ( Value - Start1 ) / (Stop1 - Start1) ) * ( Stop2 - Start2 ) ) + Start2
}

{
local PI2 := 2 * ACos(-1), Angle := PI2 / Points, HalfAngle := Angle/2.0, a := 0, a2 := 0, n := 0, buf := "", s := 0
while ( a2 < PI2 )
a2 += Angle, ++n
VarSetCapacity(buf, s := 4 * (4 * n + 2))
while ( a < PI2 )
NumPut(X + cos(a) * Radius2, &buf + 16 * (A_Index - 1), "Float")
, NumPut(Y + sin(a) * Radius2, &buf + 16 * (A_Index - 1) + 4, "Float")
, NumPut(X + cos(a+HalfAngle) * Radius1, &buf + 16 * (A_Index - 1) + 8, "Float")
, NumPut(Y + sin(a+HalfAngle) * Radius1, &buf + 16 * (A_Index - 1) + 12, "Float"), a += Angle
NumPut(NumGet(&buf+0,"Float"), &buf+s-8, "Float"), NumPut(NumGet(&buf+4,"Float"), &buf+s-4, "Float")
DllCall("Gdiplus.dll\GdipFillPolygon", "UPtr", G, "UPtr", Brush, "UPtr", &buf, "Int", 2*n+1, "Int", 0, "UInt")
}

GuiClose:
GuiEscape:
ExitApp``````

### Re: Math Functions

Posted: 21 Aug 2018, 23:06
not sure what your map() func does
: 1 ⠀⠀⠀2.
i get it now. seems like it scales a value from one range into the corresponding value in another range, right? if so i think scale() is the appropriate name

### Re: Math Functions

Posted: 21 Aug 2018, 23:59

### Re: Math Functions

Posted: 22 Aug 2018, 07:38
@nnnik I think that in this case it is not necessary, I would say that it is the obvious conversion. Also, IMO radians()/degrees() look better.
@guest3456 I was thinking something like maprange(), but scale() looks good.

### Re: Math Functions

Posted: 22 Aug 2018, 08:19
radians()/degrees() doesn't sound like its converting anything.
It seems like its creating a value of the type degree or radians - the source of their data is not mentioned.
Thats especially bad because there are multiple possible source types.

See: https://en.wikipedia.org/wiki/Angle#Units

### Re: Math Functions

Posted: 22 Aug 2018, 08:35
AHK is not a specialized/optimized language to perform mathematical operations, we do not need all kinds of conversions. Here I am only proposing the most used/common. Creating a value of type degrees/radians does not make any sense to me.
https://docs.python.org/3/library/math.html | https://processing.org/tutorials/trig/
If lexikos plans to add several types of conversions, then we can take into account the name you propose.

### Re: Math Functions

Posted: 22 Aug 2018, 10:11
- For situations like this, a list of function names for different programming languages would be useful. If anyone has any links. Unfortunately Rosetta Code does not appear to do this.
- Re. function names: I would use Fact instead of Factorial. Radians/Degrees are common names, or DegToRad/RadToDeg if people wanted. 'To' rather than '2' would probably be better for consistency, because you could end up with 'Utf82' instead of 'Utf8To' etc.
- Here are some degrees/radians solution ideas. Even Excel falls shorts re. degrees/radians in terms of being newbie-friendly, as AutoHotkey should always be. It's hard to remember when using Sin/ASin, whether to use Radians or Degrees, and which function is inside which. A potential source of needless bugs.

Code: Select all

``````;==================================================

;PSEUDOCODE
;sin(30 degrees) = 0.5
;asin(0.5) = 30 degrees

;GOOD SOLUTIONS
;the real functions would lack the underscore: Sin(30, "d") or ASin(0.5, "d")
MsgBox, % _Sin(30, "d")
MsgBox, % _ASin(0.5, "d")

MsgBox, % SinDeg(30)
MsgBox, % ASinDeg(0.5)

;OTHER SOLUTIONS
MsgBox, % Sin(Radians(30)) ;same as Excel
MsgBox, % Degrees(ASin(0.5)) ;same as Excel

PI := 4 * ATan(1)
MsgBox, % Sin(30 * (PI/180))
MsgBox, % ASin(0.5) * (180/PI)

;==================================================

{
;d = r * (180/pi)
}
{
;r = d * (pi/180)
return vDeg * 0.01745329252
}

{
;d = r * (180/pi)
}
{
;r = d * (pi/180)
return vDeg * 0.01745329252
}

{
;d = r * (180/pi)
}
{
;r = d * (pi/180)
return vDeg * 0.01745329252
}

_Sin(vAngle, vUnit:="")
{
if (vUnit = "d")
return Sin(vAngle * 0.01745329252)
else
return Sin(vAngle)
}
_ASin(vNum, vUnit:="")
{
if (vUnit = "d")
return ASin(vNum) * 57.29578
else
return ASin(vNum)
}

SinDeg(vAngle)
{
return Sin(vAngle * 0.01745329252)
}
ASinDeg(vNum, vUnit:="")
{
return ASin(vNum) * 57.29578
}

;==================================================
``````
- I've written some potential code for ATan2 and Log, here:
C++: AHK source code: potential functions - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 23&t=54392

### Re: Math Functions

Posted: 22 Aug 2018, 12:19
Limiting ourselves this early on in the development could really hinder us later on.
There are no good arguments for degrees and radians naming conventions.
Python actually forces its users to rewrite parts of their scripts with every minor update - in AHK we don't do that.
The development culture is different - therefore I wouldnt use Python as reference here.

### Re: Math Functions

Posted: 22 Aug 2018, 13:48
As I mentioned, I doubt that so many conversion functions will be added, radians/degrees are common names, I do not believe that other conversion functions are necessary with respect to this, and I do not think that these names will limit us in the future. We do not have any function that uses that form (2, To) to name them. Anyway, it is better to use To instead of 2, as jeeswg says.

### Re: Math Functions

Posted: 14 Sep 2018, 16:36
- Re. 'to', the String function checks for a ToString method, and so there might be an ObjToString function in future.

- A FloorMod function could be extremely useful as a built-in function.
- FloorMod(Dividend, Divisor): if the divisor is positive, the result is positive.
FloorDiv / FloorMod (and an 'always positive' Mod function) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=55751

- I had also thought that Combin/Permut functions (that can handle with/without repetitions) would be very useful. Familiar with Excel, I was surprised that they weren't in AutoHotkey when I first started using it.
- They are awkward because they commonly need numbers bigger than Int64 when doing the calculations, thus they would be a good candidates as built-in functions. Otherwise big number/infinite precision (numbers as strings) functions might be good as built-in functions.
- (Combin/Permut are not a personal priority of mine for the AHK v2 first release.)

- For reference here are some mathematical functions from various languages/programs. I often feel that Excel is a great model for mathematical and date functions. (Although the date functions wouldn't have to be built-in IMO.)
- (I have tried to implement Combin/Permut/big int and all (I believe) of the Excel date functions in AutoHotkey, and have released or intend to release them at some point.)
<cmath> (math.h) - C++ Reference
http://www.cplusplus.com/reference/cmath/
Math (Java Platform SE 8 )
https://docs.oracle.com/javase/8/docs/a ... /Math.html
All Mathematical Functions Defined under Math Module in Python 3
https://www.programiz.com/python-progra ... dules/math
Excel Functions List
https://www.excelfunctions.net/excel-fu ... gFunctions
- Also:
[Feature Request] Add "Sign" function - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 37&t=54044

### Re: Math Functions

Posted: 18 Sep 2018, 19:48
No constants please. 2.7182... and 3.141592... lets the user choose the precision of the float, so some calculations can be performed faster if the user wants.

All trig functions should return radians. Conversion should be left to the user, (where the precision of PI is left to them)

gamma() which is like the factorial extended would be nice as well. Also +1 for inverse/hyperbolic trig functions.

### Re: Math Functions

Posted: 18 Sep 2018, 21:03
No constants please. 2.7182... and 3.141592... lets the user choose the precision of the float, so some calculations can be performed faster if the user wants.
Is this true in AHKv2?, Do you have any script that you want to show us that supports this?.
Anyway, I do not agree, I think lexikos must decide the precision, it does not need to be too much, or at least not for the use that will be given in AHK. 3.141592 seems ok.
I'm not sure where much precision is needed, but if that's the case, I do not think AHK is the right language for it anyway.

### Re: Math Functions

Posted: 19 Sep 2018, 00:37
I don't think that limiting AHKs capabilities like that from the start will end well.

### Re: Math Functions

Posted: 19 Sep 2018, 02:25
The number is a double anyways. Specifying a less accurate number will only make make the result less accurate, not one bit faster. Unless you take, eg, pi as 3, and only make calculations with integer and integer results.

### Re: Math Functions

Posted: 19 Sep 2018, 02:33
Calculating and storing the constant once at startup seems like a good idea though.