Forum Discussion

royari's avatar
royari
Contributor
3 years ago

Goal Seek function equivalent In onestream

Hi - has anyone tried to replicate excel Goal Seek function in Onestream. We have a bonus model calculation in excel which uses excel goal seek and circular reference with iterations options in Excel...
  • ChrisLoran's avatar
    3 years ago

    Yes, but goal-seeking is definately something you don't want to put into Member Formula, or inside loops, as it is an intensive operation.

    The example code below is a good example, it uses a bisection algorithm to calculate the Square Root of a number. Basically if you know  fn(x) = 9, then  x=3.    The sqrt function is a good example where internally, it iterates and bisects various initial guesses, until it homes-in on a guess that gets to very very close to the goal.

    The function MyCalculation just returns  x * x, or x-squared.   So it uses a binary slicing algorithm to goal-seek which input number (x) would result in the desired x-squared.

    You can then implement your own formula in the MyCalculation() function, to some other calculation, and the algorithm will try to goal-seek the appropriate source amount to get the desired return amount from MyCalculation().

     

    Imports System
    Imports System.Data
    Imports System.Data.Common
    Imports System.IO
    Imports System.Collections.Generic
    Imports System.Globalization
    Imports System.Linq
    Imports Microsoft.VisualBasic
    Imports System.Windows.Forms
    Imports OneStream.Shared.Common
    Imports OneStream.Shared.Wcf
    Imports OneStream.Shared.Engine
    Imports OneStream.Shared.Database
    Imports OneStream.Stage.Engine
    Imports OneStream.Stage.Database
    Imports OneStream.Finance.Engine
    Imports OneStream.Finance.Database

    Namespace OneStream.BusinessRule.Extender.GoalSeekExample
                Public Class MainClass
                            Public Function Main(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As Object, ByVal args As ExtenderArgs) As Object

                                        Try
                                                    Select Case args.FunctionType                                                           

                                                                Case Is = ExtenderFunctionType.Unknown

                                                                            Dim tol As Double = 1E-6
                                                                            Dim [Mid] As Double = 0
                                                                            Dim goal As Double = 9
                                                                            Dim iter As Integer  = 0
                                                                            Dim lo As Double = 0
                                                                            Dim hi As Double = goal                                                                       

                                                                            Do While iter<100
                                                                                        [mid] = (lo+hi) / 2
                                                                                        Dim delta As Double = MyCalculation([mid]) - goal
                                                                                        If Math.Abs(delta) < tol Then Exit Do
                                                                                        If delta>0 Then hi=[mid] Else lo=[mid]
                                                                                        iter += 1
                                                                            Loop
                                                                            brapi.ErrorLog.LogMessage(si,"Found source amount =" & [mid].XFToStringForFormula)

                                                    End Select
                                                    Return Nothing
                                        Catch ex As Exception
                                                    Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
                                        End Try

                            End Function

     

    '---- This is the function that you are trying to goal-seek the input amount , from an expected result ---                       

                            Private Function MyCalculation(x As Double) As Double
                                        Return x*x
                            End Function

                           

                End Class

    End Namespace