malczak / SFExpression

SFExpression allow to parse mathematics strings expression and calculate them in Swift

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SFExpression

SFExpression allow to parse mathematics strings expression and calculate them in Swift.

Library is a just a wrapper around a sffe math parser created for XaoS fractal zoomer. Because of a number of operations required to draw, zoom and animate complex plane fractals the library had been designed with execution speed in mind. Its quite slow when it comes to expression parsing but is very fast when comes to expression evaluation.

Internally library is transforming expression into a call stack. Expression evalutaion is done insitu even if expression variables are modified.

Main advantages

  • easily extendable - custom variables, custom functions etc.
  • can work in any number space (even algebraic space)
  • fast :)

Weak sides

  • complicated syntax of custom functions
  • not thread save

Custom variable accessing example

let ex = SFExpression()
ex["x"] = 0.0
ex.parse("2 * sin(x) * cos(x)")

ex["x"] = 2.0
var r = ex.eval() // r = -0.756802495307928

ex["x"] = 4.0
r = ex.eval() // r = 0.989358246623382

Variable binding is a way faster way to provide variables

var x = 0.0
let expr = SFExpression()
try! expr.bindVar("x", ptr: &x)
ex.parse("2 * sin(x) * cos(x)")
    
x = 2.0
var r = ex.eval() // r = -0.756802495307928

x = 4.0
r = ex.eval() // r = 0.989358246623382

Swift callback can be provided as a custom function

var x = 1.0, y = 2.0
let expr = SFExpression()
try! expr.bindVar("x", ptr: &x)
try! expr.bindVar("y", ptr: &y)

expr.addFunction("magick", params: 2) {
      (p: UnsafeMutablePointer<sfarg>, payload: UnsafeMutablePointer<Void>) -> UnsafeMutablePointer<sfarg> in
      var arg = SFArgument(p)
      let in_y = arg.param1()
      let in_x = arg.param2()
      arg.value = sin(in_x.value) + in_y.value;
      return in_x.memory;
    }
    
expr.parse("2 * magick_f(x;y)")
expr.eval()

Example above uses helper struct SFArgument to access method arguments. To improve eval time direct access can be used

var x = 1.0, y = 2.0
let expr = SFExpression()
try! expr.bindVar("x", ptr: &x)
try! expr.bindVar("y", ptr: &y)

expr.addFunction("magick_", params: 2) {
      (p: UnsafeMutablePointer<sfarg>, payload: UnsafeMutablePointer<Void>) -> UnsafeMutablePointer<sfarg> in
      let arg = p.memory;
      let in_y = arg.parg;
      let in_x = in_y.memory.parg;
      arg.value.memory = sin(in_x.memory.value.memory) + in_y.memory.value.memory
      return in_x;
    }
    
expr.parse("2 * magick_f(x;y)")
expr.eval()

Custom methods can also be provided as Swift or C functions.

About

SFExpression allow to parse mathematics strings expression and calculate them in Swift

License:MIT License


Languages

Language:C 72.1%Language:Swift 26.2%Language:Objective-C 1.7%