Translate C code to Xojo

Your code seems to translate to:

Public Sub funcd(value As Double, Byref result As double, Byref derivative As Double)
  // funcd example matching the type funcdDelegate
  // Do your math here receiving "value" and returning the result and the first derivative

  result = cos(value) - value * value  * value
  derivative = -sin(value ) -3 * value  * value 

End Sub

Have in mind that I’m not validating the algorithm or your function, just translating them as is.

Public Sub main()
  
  // Example passing the delegated function funcd above
  Var root as double = rtsafe((New funcdDelegate(AddressOf funcd)), 0, 1) // bisection [0,1]
  
End Sub

As for the Delegate, here is how you define it:

https://documentation.xojo.com/api/language/delegate.html

Hi Rick,
I discover Delegates feature … , programing with xojo is my hobby, so i am far from
a full understanding.
Thank you for your assistance.

1 Like

It’s useful for passing different functions to be used by another functions, as:

Public Sub main()
  
  // Example using different functions (of the funcdDelegate type) and calculating their roots
  Var root1, root2, root3 as double
  root1 = rtsafe((New funcdDelegate(AddressOf MyFuncd1)), 0, 1) // bisection [0,1]
  root2 = rtsafe((New funcdDelegate(AddressOf MyFuncd2)), 0, 1) // bisection [0,1]
  root3 = rtsafe((New funcdDelegate(AddressOf MyFuncd3)), 0, 1) // bisection [0,1]

End Sub

I learned today that besides Delegates in Xojo being Objects, they have an internal different treatment and auto instantiate themselves when sent as Pointers in parameters, so, this may work:

Public Sub main()
  
  // Example using different functions (of the funcdDelegate type) and calculating their roots
  Var root1, root2, root3 as double
  root1 = rtsafe(AddressOf MyFuncd1, 0, 1) // bisection [0,1]
  root2 = rtsafe(AddressOf MyFuncd2, 0, 1) // bisection [0,1]
  root3 = rtsafe(AddressOf MyFuncd3, 0, 1) // bisection [0,1]

End Sub

Realy very useful and helpful.
Thank you Rick for your help and assistance.

1 Like

Hi Rick,
I want to compare rtsafe() to NewtonRapson().
Both use same fx and fdx.
this is NewtonRaphson() where funcd must be invoked.

NewtRaphson(x1 as double, x2 as double, maxiter as integer=100, accuracy as double = 3E-6) as double
dim xi,xf,s,eps as double
dim i as integer
eps =accuracy

i=0
xi=(x1+x2)*.5

while (abs(s)>eps or i<maxiter)
i=i+1
xf=xi-fx(xi)/dfdx(xi) //this line must be reached by funcd instead of “dfdx, derivative” and "fx, function)
s=xf-xi
xi=xf

Wend

return xf

End SUB

Rick,
It’s Ok, already coded.

1 Like

Hi Rick,
rtsafe() translate is running properly, so i need to know how many loops are done.
How to return the number of iteration, i mean root and iter.

Public Function rtsafei(funcDeriv As funcdDelegate, x1 As Double, x2 As Double, maxIter As Integer = 100, accuracy As Double = 3E-8) as Pair // root : num of iterations 
  Var j As Integer
  Var df,dx,dxold,f,fh,fl As Double
  Var temp,xh,xl, rts As Double
  
  funcDeriv.Invoke(x1,fl,df)
  funcDeriv.Invoke(x2,fh,df)
  
  If ((fl > 0.0 And fh > 0.0) Or (fl < 0.0 And fh < 0.0)) Then
    Var ex As New RuntimeException
    ex.Message = "Root must be bracketed in rtsafe"
    Raise ex
    Return 0.0 : 0
  End If
  
  If (fl = 0.0) Then Return x1 : 1
  If (fh = 0.0) Then Return x2 : 1
  
  If (fl < 0.0) Then
    xl = x1
    xh = x2
  Else
    xh = x1
    xl = x2
  End If
  
  rts = 0.5 *(x1 + x2)
  dxold = abs(x2 - x1)
  dx = dxold
  
  funcDeriv.Invoke(rts,f,df)
  
  For j = 1 To maxIter
    
    If (((rts - xh) *df - f) *((rts - xl) *df - f) > 0.0) Or (abs(2.0 *f) > abs(dxold *df)) Then
      dxold = dx
      dx = 0.5 *(xh - xl)
      rts = xl + dx
      If (xl = rts) Then Return rts : j
    Else
      dxold = dx
      dx = f / df
      temp = rts
      rts = rts - dx
      If (temp = rts) Then Return rts : j
    End If
    
    If (abs(dx) < accuracy) Then Return rts : j
    
    funcDeriv.Invoke(rts, f, df)
    
    If (f < 0.0) Then
      xl = rts
    Else
      xh = rts
    End If
    
  Next
  
  Var ex As New RuntimeException
  ex.Message = "Maximum number of iterations exceeded in rtsafe"
  Raise ex
  
  Return 0.0 : maxIter + 1
  
End Function

// rtsafei() returns a “Pair”, where the left is root, and right the number of iterations

// I typed directly here without testing. Check it.

https://documentation.xojo.com/api/data_types/pair.html

1 Like

Rick its running properly Rtsafe C code gives same root value with 3 loops.
Same under matlab, accuracy used = 1.0E-7
I don’t calculate execution time but so fast, less then 0.1 sec. under xojo with 6 iter.

attached screenshot NR brackted, NR xo=0, Combined NR/Bisect (brackted) , Rtsafe and Rtsa

fei .
Thank you so much.

1 Like

The original C code uses a float, half of the current supported decimal accuracy of the Xojo code using Doubles, so probably this version goes a bit further looking for more precise matches dividing dx with “more decimals” and it takes the double if its iterations to find the exact roots or dx < accuracy.

1 Like

Yes i agree xojo is running in 64bit environment.
Anyway xojo is so fast, of course less than low level C.
Big difference when code is interpreted running IDE and when compiled.
I do a test (benchmark) for floating; 4.5 sec (IDE) and 0.8 sec (compiled) on a Proc i7 (4th gen) under win 10.
Thank a lot, Rick .

1 Like