Thursday, August 13, 2020

You are not logged in.

**Fredrik71****Member**- Registered: 2019-10-23
- Posts: 333

Hi All, I hope you all is well and happy.

I was testing a function that position object in repeat loop to use sin and cos to form a circle.

My first test use SatimageOSAX and it does do what I want.

So next test was to try to use JavaScript in AppleScript, I got a value for Math.sin

but I do not know how to set a applescript variable in JavaScript call with OSAKit.

Next I try other sin function I know, all gave me different result.

So my question is, what is the best approach to use in AppleScript TODAY ?? for math functions.

Regards

## Applescript:

use framework "OSAKit"

-- use script "calcLIBAS"

use application "SatimageOSAX"

-- set js_sin to evalOSA("JavaScript", "Math.sin(25)")

--> -0.132351750097773

-- SatimageOSAX

set r_sin1 to sin (25)

--> -0.132351750098

set d_sin to sin (25 * (pi / 180))

--> 0.422618261741

-- calcLIBAS

-- set r_sin2 to sin (25)

--> -0.132351750098

-- set d_sin to sin (25 * (pi / 180)) --> Doesn't Work.

-- 0.0

-- set d_sin to f_sin(25)

-- 0.422618261741

-- set r_sin to 0.422618261741 * (180 / pi)

--> 24.214242742914

-- set d_sin to sine_of(25)

-- 0.422618261741

-- set r_sin to 0.422618261741 * (180 / pi)

--> 24.214242742914

-- evalOSA("JavaScript", "Math.sin('25')")

--> -0.132351750097773

-- evalOSA("JavaScript", "Math.sin(25 * (Math.PI / 180))")

--> 0.4226182617406994

on evalOSA(strLang, strCode)

set ca to current application

set oScript to ca's OSAScript's alloc's initWithSource:strCode ¬

|language|:(ca's OSALanguage's languageForName:(strLang))

set {blnCompiled, oError} to oScript's compileAndReturnError:(reference)

if blnCompiled then

set {oDesc, oError} to oScript's executeAndReturnError:(reference)

if (oError is missing value) then return oDesc's stringValue as text

end if

return oError's NSLocalizedDescription as text

end evalOSA

on sine_of(x)

repeat until x ≥ 0 and x < 360

if x ≥ 360 then

set x to x - 360

end if

if x < 0 then

set x to x + 360

end if

end repeat

--convert from degrees to radians

set x to x * (2 * pi) / 360

set answer to 0

set numerator to x

set denominator to 1

set factor to -(x ^ 2)

repeat with i from 3 to 40 by 2

set answer to answer + numerator / denominator

set numerator to numerator * factor

set denominator to denominator * i * (i - 1)

end repeat

return answer

end sine_of

to _sin(x)

set x to (x mod 360) * (pi / 180) -- convert from degrees to radians

set isNeg to x < 0

if isNeg then set x to -x

set y to (x * (4 / pi)) div 1

set z to y - (y * 0.0625 div 1) * 16

if z mod 2 is 1 then

set z to z + 1

set y to y + 1

end if

set z to z mod 8

if z > 3 then

set isNeg to not isNeg

set z to z - 4

end if

set z2 to ((x - y * 0.785398125648) - y * 3.77489470793E-8) - y * 2.695151429079E-15

set zz to z2 * z2

if z is 1 or z is 2 then

set y to 1.0 - zz / 2 + zz * zz * (((((-1.13585365213877E-11 * zz + 2.08757008419747E-9) * zz - 2.75573141792967E-7) * zz + 2.48015872888517E-5) * zz - 0.001388888889) * zz + 0.041666666667)

else

set y to z2 + z2 * zz * (((((1.58962301576546E-10 * zz - 2.50507477628578E-8) * zz + 2.75573136213857E-6) * zz - 1.98412698295895E-4) * zz + 0.008333333333) * zz - 0.166666666667)

end if

if isNeg then set y to -y

return y

end _sin

to f_sin(x)

try

return _sin(x as number)

on error eText number eNumber from eFrom to eTo

_error("sin", eText, eNumber, eFrom, eTo)

end try

end f_sin

The best knowledge is always free, we share ideas, thoughts and expressions. So we could build better worlds together.

Offline

**Fredrik71****Member**- Registered: 2019-10-23
- Posts: 333

## Applescript:

-- SatimageOSAX

set s to sin (pi / 2)

--> 1.0

## Applescript:

evalOSA("JavaScript", "Math.sin(Math.PI/2)")

--> 1.0

The above return 1 and that is correct.

## Applescript:

-- calcLIBAS

set s to sin (pi / 2)

--> 0.841470984808

But this one did something else.

The best knowledge is always free, we share ideas, thoughts and expressions. So we could build better worlds together.

Offline

**Shane Stanley****Member**- From:: Australia
- Registered: 2002-12-07
- Posts: 6440

You can do it using the JavaScriptCore framework:

## Applescript:

use AppleScript version "2.4" -- Yosemite (10.10) or later

use framework "Foundation"

use framework "JavaScriptCore"

use scripting additions

doJsMath("sin", 25)

doJsMath("sin", 25 * (pi / 180))

on doJsMath(theMethod, argsList)

if class of argsList is not list then set argsList to {argsList}

set theContext to current application's JSContext's new()

set theMathObject to theContext's objectForKeyedSubscript:"Math"

return (theMathObject's invokeMethod:theMethod withArguments:argsList)'s toDouble()

end doJsMath

But it's more efficient to re-use the same context, something like this more generalised example:

## Applescript:

use AppleScript version "2.4" -- Yosemite (10.10) or later

use framework "Foundation"

use framework "JavaScriptCore"

use scripting additions

property theMathObject : missing value

doJsMath("sin", 25)

doJsMath("sin", 25 * (pi / 180))

on doJsMath(theMethod, argsList)

if class of argsList is not list then set argsList to {argsList}

set theValue to (mathObject()'s invokeMethod:theMethod withArguments:argsList)'s toObject()

-- convert to AS value

return item 1 of ((current application's NSArray's arrayWithObject:theValue) as list)

end doJsMath

on mathObject()

if theMathObject = missing value then

set theContext to current application's JSContext's new()

set theMathObject to theContext's objectForKeyedSubscript:"Math"

end if

return theMathObject

end mathObject

Shane Stanley <sstanley@myriad-com.com.au>

www.macosxautomation.com/applescript/apps/

latenightsw.com

Offline

I wrote JavaScript Core wrapper + sdef = "calcLibAS" script library.

It has 35 math function calls in it.

I think this is best approach for non-Cocoa scripting scripters.

http://piyocast.com/as/asinyaye

I wrote thousands of AppleScript to realize my idea. Natural language interface, voice recognition commander and so on. Though my mother toungue is strange language, Japanese, my most frequently write language is AppleScript. I believe it is for making things easy and powerful.

Offline

**KniazidisR****Member**- Registered: 2019-03-03
- Posts: 1265

Shane Stanley wrote:

But it's more efficient to re-use the same context, something like this more generalised example:

As I understand it, Fredrik71 wants to have the fastest code to calculate sine or cosine. Undoubtedly, code written in machine language will give a speed record, since the sine or cosine is calculated by decomposing into a **Taylor series or a similar series**, with a **certain desired accuracy**. I believe that the JavaScript framework provided in your post, uses machine code, but I don’t see where **precision** is set here?

It would be incorrect to compare the speed of different scripts, not to mention the **desired accuracy**, to calculate the sine and cosine.

By the way, this is most likely why Fredrik 71, using calcLIBAS, gets a less accurate result than in 2 other cases. It’s just that the calcLIBAS algorithm pursues less accuracy than 2 others.

In the following posts I provide **plain AppleScript** versions of sin(x), cos(x), e(x), tan(x) :

*Last edited by KniazidisR (2020-03-28 10:12:23 pm)*

Model: MacBook Pro

OS X: Catalina 10.15.4

Web Browser: Safari 13.1

Ram: 4 GB

Offline

**Shane Stanley****Member**- From:: Australia
- Registered: 2002-12-07
- Posts: 6440

KniazidisR wrote:

It would be incorrect to compare the speed of different scripts, not to mention the

desired accuracy, to calculate the sine and cosine.

Javascript uses standard double precision floating point numbers, the same as pretty much every other language. I don't think accuracy is an issue with JavaScriptCore (and hence with Takaaki's library).

Shane Stanley <sstanley@myriad-com.com.au>

www.macosxautomation.com/applescript/apps/

latenightsw.com

Offline

**KniazidisR****Member**- Registered: 2019-03-03
- Posts: 1265

I tested and as I see, the accuracy better than 1.0E-10 in the AppleScript doesn't make sense. And, I found 1 error in my script. So, I updated it.

NOTE: the ASObjC variant from Shane Stanley is mach faster, but I think, the plain AppleScript version won't hurt anyone either. My plain AppleScript version calculates the sine about 1 or 2 milliseconds, on my machine.

*Last edited by KniazidisR (2020-03-28 02:35:20 am)*

Model: MacBook Pro

OS X: Catalina 10.15.4

Web Browser: Safari 13.1

Ram: 4 GB

Offline

**Fredrik71****Member**- Registered: 2019-10-23
- Posts: 333

Thanks, all for your inputs.

Lets have example to test.

In this code I use SatimageOSAX sin and cos function to position shape object in Numbers

to form a circle. Very simple Script. When I use other sin function I got different result.

So could anyone test it... with your version of sin... do also test with different property.

regards.

EDIT:

*** What I'm interesting in is accurate approach before speed, but of course speed is wonderful.

*** If the calculation is not accurate the result could be wrong.

## Applescript:

use application "SatimageOSAX"

--~~~~~~~~~~~~~~~~~~~~~~~

property shapeAmount : 12

property shapeGap : 100

property shapeWidth : 25

property shapeHeight : 25

property xOrigin : 250

property yOrigin : 250

--~~~~~~~~~~~~~~~~~~~~~~~

repeat with i from 1 to shapeAmount

set tAngle to (i * (360 / shapeAmount))

set tRadians to tAngle * (2 * pi) / 360

set xCentre to xOrigin + shapeGap * (cos (tRadians))

set yCentre to yOrigin + shapeGap * (sin (tRadians))

set xPos to xCentre

set yPos to yCentre

tell application id "com.apple.iWork.Numbers"

set theSheet to sheet 1 of document 1

tell theSheet

make new shape with properties {position:{xPos, yPos}, width:shapeWidth, height:shapeHeight}

end tell

end tell

end repeat

*Last edited by Fredrik71 (2020-03-28 02:57:26 am)*

The best knowledge is always free, we share ideas, thoughts and expressions. So we could build better worlds together.

Offline

**Fredrik71****Member**- Registered: 2019-10-23
- Posts: 333

Hi Takaaki, I know...

Did you also see that your code library didn't return 1 in this function.

## Applescript:

set s to sin (pi / 2)

Test my Script in Number in this thread with your library and you will see a different

result compare to SatimageOSAX.

maro wrote:

I wrote JavaScript Core wrapper + sdef = "calcLibAS" script library.

Offline

**Fredrik71****Member**- Registered: 2019-10-23
- Posts: 333

Thanks to much Shane, I will test your code...

Shane Stanley wrote:

You can do it using the JavaScriptCore framework

The way I did it with OSAKit, was that the old way to do it ??, any comment...

Offline

This returns 1.0 for me.

You have to install library to your computer before execution.

## Applescript:

use script "calcLibAS" --Need to install calcLibAS --http://piyocast.com/as/wp-content/uploads/2019/08/calcLibASv1.5.zip

set s to sin (pi / 2)

--> 1.0

Fredrik71 wrote:

Hi Takaaki, I know...

Did you also see that your code library didn't return 1 in this function.## Applescript:

set s to sin (pi / 2)

Test my Script in Number in this thread with your library and you will see a different

result compare to SatimageOSAX.maro wrote:I wrote JavaScript Core wrapper + sdef = "calcLibAS" script library.

I wrote thousands of AppleScript to realize my idea. Natural language interface, voice recognition commander and so on. Though my mother toungue is strange language, Japanese, my most frequently write language is AppleScript. I believe it is for making things easy and powerful.

Offline

**KniazidisR****Member**- Registered: 2019-03-03
- Posts: 1265

Fredrik71,

Try this code (here I improved my plain AppleScript version of SIN and COS handlers). Let "SatimageOSAX" rest for a while:

## Applescript:

property shapeAmount : 12

property shapeGap : 100

property shapeWidth : 25

property shapeHeight : 25

property xOrigin : 250

property yOrigin : 250

repeat with i from 1 to shapeAmount

set tAngle to (i * (360 / shapeAmount))

set tRadians to tAngle * (2 * pi) / 360

set xCentre to xOrigin + shapeGap * (cos(tRadians))

set yCentre to yOrigin + shapeGap * (sin(tRadians))

set xPos to xCentre

set yPos to yCentre

tell application id "com.apple.iWork.Numbers"

activate

set theSheet to sheet 1 of document 1

tell theSheet

make new shape with properties {position:{xPos, yPos}, width:shapeWidth, height:shapeHeight}

end tell

end tell

end repeat

on cos(x1 as real)

set theAccuracy to 1.0E-12 -- the precision

set aPreviousCos to 1

set aCos to 1

set a to 1

repeat with n from 2 to 100 by 2

set a to -a * x1 * x1 / (n - 1) / n -- new Tailor serie's member

set aCos to aCos + a

if aCos > aPreviousCos then

if aCos - aPreviousCos < theAccuracy then exit repeat

else

if aPreviousCos - aCos < theAccuracy then exit repeat

end if

set aPreviousCos to aCos

end repeat

if aCos < theAccuracy then set aCos to 0.0

return aCos

end cos

on sin(x1 as real)

set theAccuracy to 1.0E-12 -- the precision

set aPreviousSin to 1

set aSin to x1

set a to 1

repeat with n from 2 to 100 by 2

set a to -a * x1 * x1 / (n - 1) / n

set aSin to aSin + a * x1 / (n + 1) -- add new Tailor serie's member

if aSin > aPreviousSin then

if aSin - aPreviousSin < theAccuracy then exit repeat

else

if aPreviousSin - aSin < theAccuracy then exit repeat

end if

set aPreviousSin to aSin

end repeat

if aSin < theAccuracy then return 0.0

return aSin

end sin

*Last edited by KniazidisR (2020-03-29 04:35:37 am)*

Model: MacBook Pro

OS X: Catalina 10.15.4

Web Browser: Safari 13.1

Ram: 4 GB

Offline

**Shane Stanley****Member**- From:: Australia
- Registered: 2002-12-07
- Posts: 6440

Fredrik71 wrote:

The way I did it with OSAKit, was that the old way to do it ??, any comment...

I'm not sure why you used OSAKit.

Shane Stanley <sstanley@myriad-com.com.au>

www.macosxautomation.com/applescript/apps/

latenightsw.com

Offline

**Fredrik71****Member**- Registered: 2019-10-23
- Posts: 333

maro wrote:

This returns 1.0 for me. You have to install library to your computer before execution.

## Applescript:

use script "calcLibAS"

get its version of script "calcLibAS"

--> "1.5"

set s to sin (pi / 2)

--> 0.841470984808

Very strange on my Mojave 10.14.3 I do not get 1.0 with your library.

Offline

**Fredrik71****Member**- Registered: 2019-10-23
- Posts: 333

Shane Stanley wrote:

I'm not sure why you used OSAKit.

It was someone at Omni group forum who share the code, so I try to use it.

To be honest its not easy to find information about OSAKit.

But from this post.

https://boredzo.org/blog/archives/2008- … day-osakit

I understand your way is far more better, and that is the one I will use, Thanks Shane.

Offline

**Fredrik71****Member**- Registered: 2019-10-23
- Posts: 333

Thanks, I will try your code, do you have also 'tan' ??

KniazidisR wrote:

Try this code (here I improved my plain AppleScript version of SIN and COS handlers).

Offline

**KniazidisR****Member**- Registered: 2019-03-03
- Posts: 1265

Fredrik71 wrote:

Thanks, I will try your code, do you have also 'tan' ??

I don't have 'tan' yet, but will write now. By the way, 'exp' function I wrote right now:

## Applescript:

my exp(-5.8) -- RESULT: 0.003027554745

---------------------------------------------------------------------------------------

on exp(x1 as real)

set theAccuracy to 1.0E-12 -- the precision

set aPreviousExp to 1

set aExp to 1

set a to 1

repeat with n from 2 to 100

set a to a * x1 / (n - 1)

set aExp to aExp + a -- add new Tailor serie's member

if aExp > aPreviousExp then

if aExp - aPreviousExp < theAccuracy then exit repeat

else

if aPreviousExp - aExp < theAccuracy then exit repeat

end if

set aPreviousExp to aExp

end repeat

if aExp < theAccuracy then return 0.0

return aExp

end exp

*Last edited by KniazidisR (2020-03-29 04:36:07 am)*

Model: MacBook Pro

OS X: Catalina 10.15.4

Web Browser: Safari 13.1

Ram: 4 GB

Offline

**Fredrik71****Member**- Registered: 2019-10-23
- Posts: 333

Here is the code that use Shane's JavaScriptCore.

If someone like to use this code, this website from mozilla is good research.

https://developer.mozilla.org/en-US/doc … _and_dates

JavaScript use IEEE 754 Standard for numbers.

https://en.wikipedia.org/wiki/Double-pr … int_format

## Applescript:

use AppleScript version "2.4" -- Yosemite (10.10) or later

use framework "Foundation"

use framework "JavaScriptCore"

use scripting additions

property theMathObject : missing value

property shapeAmount : 12

property shapeGap : 50

property shapeWidth : 10

property shapeHeight : 10

property xOrigin : 250

property yOrigin : 250

repeat with i from 1 to shapeAmount

set tAngle to (i * (360 / shapeAmount))

set tRadians to tAngle * (2 * pi) / 360

set xCentre to xOrigin + shapeGap * (doJsMath("cos", (tRadians)))

set yCentre to yOrigin + shapeGap * (doJsMath("sin", (tRadians)))

set xPos to xCentre

set yPos to yCentre

tell application id "com.apple.iWork.Numbers"

activate

set theSheet to sheet 1 of document 1

tell theSheet

make new shape with properties {position:{xPos, yPos}, width:shapeWidth, height:shapeHeight}

end tell

end tell

end repeat

on doJsMath(theMethod, argsList)

if class of argsList is not list then set argsList to {argsList}

set theValue to (mathObject()'s invokeMethod:theMethod withArguments:argsList)'s toObject()

-- convert to AS value

return item 1 of ((current application's NSArray's arrayWithObject:theValue) as list)

end doJsMath

on mathObject()

if theMathObject = missing value then

set theContext to current application's JSContext's new()

set theMathObject to theContext's objectForKeyedSubscript:"Math"

end if

return theMathObject

end mathObject

*Last edited by Fredrik71 (2020-03-28 02:13:08 pm)*

Offline

**Fredrik71****Member**- Registered: 2019-10-23
- Posts: 333

Thanks to much, Math Library could be very useful in many ways.

KniazidisR wrote:

I don't have 'tan' yet, but will write now. By the way, 'exp' function I wrote right now:

Offline

**KniazidisR****Member**- Registered: 2019-03-03
- Posts: 1265

The expansion of the tang(x) function in a Taylor/Maclaurin series has an intricate structure using Bernoulli numbers, so an efficient code cannot be obtained from it. It would be better to apply the sine to cosine division algorithm here:

## Applescript:

my tan(pi / 3) -- RESULT: 1.732050807569

on tan(x1 as real) -- (-π/2<x<π/2) -- tangent of acute angle

if (x1 ≥ pi / 2) or (x1 ≤ -pi / 2) then return "The parameter x1 should be < π/2 and > -π/2"

set theAccuracy to 1.0E-12 -- the precision

set aSin to x1

set aCos to 1

set a to 1

set aPreviousTan to 1

repeat with n from 2 to 100 by 2

set a to -a * x1 * x1 / (n - 1) / n

set aCos to aCos + a -- add new Tailor serie's member

set aSin to aSin + a * x1 / (n + 1) -- add new Tailor serie's member

set aTan to aSin / aCos

if aTan > aPreviousTan then

if aTan - aPreviousTan < theAccuracy then exit repeat

else

if aPreviousTan - aTan < theAccuracy then exit repeat

end if

set aPreviousTan to aTan

end repeat

if aTan < theAccuracy then return 0.0

return aTan

end tan

*Last edited by KniazidisR (2020-03-29 04:36:36 am)*

Model: MacBook Pro

OS X: Catalina 10.15.4

Web Browser: Safari 13.1

Ram: 4 GB

Offline

**Yvan Koenig****Member**- Registered: 2006-09-14
- Posts: 4568

As the calculations are supposed to be used with a Numbers document, why not ask Numbers to do the job? As far as I know it's what spreadsheets are designer to achieve.

## Applescript:

#------------------------------------------------------------------------------

#

# How to use Numbers to calculate our coordinates

#

# Yvan KOENIG (VALLAURIS, France) samedi 28 mars 2020 16:40:16

#

#------------------------------------------------------------------------------

set theDoc to "calculs.Numbers"

-- Localize some values

set deci_loc to text 2 of ((1 / 2) as text)

tell application "Numbers"

set row_loc to localized string "ROW" from table "TSCalculationEngine" --> LIGNE

set pi_loc to localized string "PI" from table "TSCalculationEngine"

set cos_loc to localized string "COS" from table "TSCalculationEngine"

set sin_loc to localized string "SIN" from table "TSCalculationEngine"

set average_loc to localized string "AVERAGE" from table "TSCalculationEngine" --> MOYENNE (not used here)

set autofillCells_loc to localized string "Autofill Cells" from table "TSTables"

tell document theDoc to tell sheet 1 to tell table 1

-- Define the constants

set shapeAmount to 12

set shapeGap to 50

set shapeWidth to 10

set shapeHeight to 10

set xOrigin to 250

set yOrigin to 250

-- fill the table with these constants

set value of cell "A2" to shapeAmount

set value of cell "B2" to shapeGap

set value of cell "C2" to shapeWidth

set value of cell "D2" to shapeHeight

set value of cell "E2" to xOrigin

set value of cell "F2" to yOrigin

set value of cell "A4" to "=" & row_loc & "()-3"

set value of cell "B4" to "=$A4*360÷$A$2"

set value of cell "C4" to "=$B4×2×" & pi_loc & "()÷360"

set value of cell "D4" to "=$E$2+($B$2×" & cos_loc & "($C4))"

set value of cell "E4" to "=$F$2+($B$2×" & sin_loc & "($C4))"

set theRange to (name of cell "A4") & ":" & name of cell (4 - 1 + shapeAmount) of column "E"

set selection range to range theRange

tell application id "com.apple.systemevents" to tell process "Numbers"

set frontmost to true

tell menu bar 1 to tell menu bar item 6 to tell menu 1 to tell menu item autofillCells_loc to tell menu 1 to click menu item 3 -- Autofill downward

end tell

-- Now you have the wanted xPos in cells D4 thru D15

-- Now you have the wanted yPos in cells E4 thru E15

end tell -- the doc…

end tell -- Numbers

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) samedi 28 mars 2020 17:46:16

Offline

**Fredrik71****Member**- Registered: 2019-10-23
- Posts: 333

Google gave this: tan (pi/3) --> 1.73205080757

KniazidisR wrote:

The expansion of the tang(x) function in a Taylor/Maclaurin series has an intricate structure using Bernoulli numbers, so an efficient code cannot be obtained from it. It would be better to apply the sine to cosine division algorithm here

Offline

Why don't you use macOS 10.14.6 ? Today, the early version of macOS is buggy everywhere.

I don't believe the result of the early version of every macOS major update.

Fredrik71 wrote:

maro wrote:This returns 1.0 for me. You have to install library to your computer before execution.

## Applescript:

use script "calcLibAS"

get its version of script "calcLibAS"

--> "1.5"

set s to sin (pi / 2)

--> 0.841470984808Very strange on my Mojave 10.14.3 I do not get 1.0 with your library.

I wrote thousands of AppleScript to realize my idea. Natural language interface, voice recognition commander and so on. Though my mother toungue is strange language, Japanese, my most frequently write language is AppleScript. I believe it is for making things easy and powerful.

Offline

**Yvan Koenig****Member**- Registered: 2006-09-14
- Posts: 4568

maro wrote:

Why don't you use macOS 10.14.6 ? Today, the early version of macOS is buggy everywhere.

I don't believe the result of the early version of every macOS major update.

Those who bought a mac since November 2019 have no alternative, their machine run only Catalina.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 29 mars 2020 04:44:43

Offline

**Fredrik71****Member**- Registered: 2019-10-23
- Posts: 333

Takaaki, I will do this update, and I will let you know... but I'm not ready to go to Catalina.

Offline