How to get result from framework Accelerate's function

asobjc
foundation

(Thierry) #1

Hello,

I’m trying to get some results from a few functions of Accelerate framework but I don’t know how to. So far, I’ve worked with the topics ‘vDSP’ and ‘vectLib’ trying with "current application’s " and simple call, like this script below:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use framework "Accelerate"

set someInitialVector to {1 / 4, 1 / 2, 3 / 4, 1, 5 / 4, 1 / 3}
set n to the count of someInitialVector
set aScalar to 4

set arrayInput to current application's NSArray's arrayWithArray:someInitialVector
set arrayOutput to current application's NSMutableArray's arrayWithCapacity:n
set arrayCount to current application's NSNumber's numberWithInt:n

-- vDSP
set scalar_vDSP to current application's NSNumber's numberWithFloat:aScalar
set arrayStrides_vDSP to current application's NSNumber's numberWithInt:n
try
	get current application's vDSP_vsmul(arrayInput, arrayStrides_vDSP, scalar_vDSP, arrayOutput, arrayStrides_vDSP, arrayCount)
	-- error "Il est impossible de poursuivre vDSP_vsmul." number -1708
on error
	get vDSP_vsmul(arrayInput, arrayStrides_vDSP, scalar_vDSP, arrayOutput, arrayStrides_vDSP, arrayCount)
	--*** -[BAGenericObjectNoDeleteOSAID vDSP:vsmul]: unrecognized selector sent to object <BAGenericObjectNoDeleteOSAID @0x6000004348c0: OSAID(2) ComponentInstance(0x83000a)>
end try

--vectLib
try
	get current application's vvcospif(arrayOutput, arrayInput, arrayCount)
	-- error "Il est impossible de poursuivre vvcospif." number -1708
on error
	get vvcospif(arrayOutput, arrayInput, arrayCount)
	--error "*** -[BAGenericObjectNoDeleteOSAID vvcospif]: unrecognized selector sent to object <BAGenericObjectNoDeleteOSAID @0x618000621060: OSAID(2) ComponentInstance(0x81000d)>" number -10 000
end try

Obviously, getting current application is not the way to go but I don’t know what to say about this unrecognized selector.

Any idea on how to get the correct result?

  • With vDSP, expected result is {1,2,3,4,5,4/3}

  • With vectLib --> {~0.71, 0, ~(-0.71), -1, (~-0.71), ~0.86}

Thank you.


(Shane Stanley) #2

You’re unlikely to be able to use much, if anything, in the Accelerate framework because the AppleScript scripting bridge doesn’t support most of the types its functions use.


(Thierry) #3

Any workaround? Like using some kind of intermediate between the Bridge and the Accelerate framework that I could invoke to do and (then) undo these types? Or another method that can do trig, linear algebra, reversing matrices, matrice determinants calculations and long sums like computing a Taylor series ?

Thanks.


(Jim Underwood) #4

You might consider using JavaScript for Automation (JXA). It provides the same access to apps as AppleScript, and JavaScript has many libraries written for it.

Try this Google search:
JavaScript trig, linear algebra, reversing matrices, matrix determinants - Google Search

Looks like some promising hits.


(Thierry) #5

Then, within an Applescript, I would run a javaScript containing a known function from either built-in or from math.js and retrieve the result for trig/exp/ln and matrice/array calculus (I would still need summation). However, I’d rather stay within Applescript and not having to add any module (math.js) with the script library that I wrote a few years back and I’d like to improve its speed (determinants and summations, mostly) as well as calculating reverse matrix.

So for now, I’ll keep this idea in mind if I don’t find what I’m looking for, that is, staying within AS & ASObjC. Thanks for the help.


(Shane Stanley) #6

The only thing I can think of is a new framework wrapping the calls you want in Objective-C that can be called from AppleScript. If it’s only a handful of things, that’s not too big an effort, but if you want access to a lot of stuff, it’s going to be a big project.

Have you looked at the scripting additions from Satimage?


(Jim Underwood) #7

I don’t think that will work. You can use an AppleScript Script Library from JXA, but NOT vise-versa. The only way I know of using JavaScript in an AppleScript is by using a Browser app.

You could write a JXA script library to just do the core math, and call that from an AppleScript.

EDIT: 2017-10-14 9:07 PM CT
Sorry, I had a brain fart when I posted that, which obviously conflicts with my above statement.

If the Satimage.osax (or other scripting additions that they offer) that @ShaneStanley suggested will provide what you need, then that is a good option. I’ve used it a lot with great success.


(Thierry) #8

Well, it could be; I’m just starting to look into it. But considering where I’m at with Objective-C now, whether it’s a handful or not, it would still be a big project for me.

I did and I enjoy quite a bit the ‘evalFormula’ call. However, since I have shared this library already with people who are cold at the idea of adding stuff they don’t know much about, I removed it from this project early on stuck on the standard installation. I may come back to it or take the JavaScript route as proposed in another reply.

In the mean time, I’ll upgrade this library a bit here, a bit there with what is available with ASObjC.

Thanks for the help.


(Jim Underwood) #9

Did you see the Satimage Numerics.osax? Looks like it might have much/all of what you need. See Dictionary of Numerics.


(Thierry) #10

Bummer!

I know this addition. Your reply was just faster than mine!

Thanks again for your input.


(Thierry) #11

That’s right! It does and even more. I don’t close the door on it (neither with your other suggestion); I will just look into a way to use ASObjc a bit more to improve this library before.


(Shane Stanley) #12

There are a couple of other ways. For fairly simple stuff, you can do this sort of thing:

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "JavaScriptCore"

set theContext to current application's JSContext's new()
set theJSVaue to theContext's evaluateScript:"Math.tan(Math.PI/3)"
set theResult to theJSVaue's toObject() as real

To load a JXA script library and call a function, you can do this:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use framework "OSAKit"
use scripting additions

try -- will fail because it's js
	script "JSTest.scpt"
on error from jsLib -- jsLib will refer to lib
	set jsLibPath to POSIX path of (jsLib as alias)
	-- load the lib
	set {myJSLib, theError} to current application's OSAScript's alloc()'s initWithContentsOfURL:(current application's |NSURL|'s fileURLWithPath:jsLibPath) |error|:(reference)
	if myJSLib is missing value then error (theError's localizedDescription()) as text
end try

my callFunction:"doIt" withArgs:{2, 2} inJSLib:myJSLib
--> 4

on callFunction:funcName withArgs:argsList inJSLib:myJSLib
	set {theResult, theError} to myJSLib's executeHandlerWithName:funcName arguments:argsList |error|:(reference)
	if theResult is missing value then error (theError's localizedDescription()) as text
	-- hack to convert from descriptor to correct AS class
	return item 1 of ((current application's NSArray's arrayWithObject:theResult) as list)
end callFunction:withArgs:inJSLib:

But there’s obviously a bit of overhead in both of them.


(Jim Underwood) #13

Shane, thank you so much. This looks terrific! :+1:

I had no idea, and I’m not sure if anyone else did either. If they did, they are keeping it to themselves. :wink:


(Shane Stanley) #14

Well I did post similar code elsewhere in reply to some guy called Jim in another place some time ago :wink:


(Jim Underwood) #15

That must have been my evil twin Jim who never remembers anything. :wink:

IAC, I have Evernoted it now, so I, the good twin, will never forget.