Goal Seek function equivalent In onestream
- 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.DatabaseNamespace 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 ObjectTry
Select Case args.FunctionTypeCase 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 = goalDo 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 TryEnd 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 FunctionEnd Class
End Namespace