Iterative Calculation System

Share your advanced PureBasic knowledge/code with the community.
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Iterative Calculation System

Post by StarBootics »

Hello everyone,

Sometime we have to deal with complex equation difficult to solve for a specific variable. So instead of wasting time solve equation, just go strait forward with the unsolvable equation and perform a binary search on the value required to match the expected result. See the given example to figure out what I mean.

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Iterative Calculation System
; File Name : IterativeCalculation.pb
; File version: 1.0.0
; Programming : OK
; Programmed by : StarBootics
; Date : 20-09-2013
; Last Update : 20-09-2013
; PureBasic code : V5.20 LTS
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Prototype.d ProtoCalculator(Input.d, *Pointer)

Procedure.d IterativeCalculation(Min.d, Max.d, Target.d, Calculator.i, *CalculatorExtraParam)
  
  Calcul.ProtoCalculator = Calculator

  While Min <= Max
    
    Input.d = (Min + Max) / 2.0
    Output.d = Calcul(Input, *CalculatorExtraParam)
    
    If Output < Target
      Min = Input
    ElseIf Output > Target
      Max = Input
    EndIf
    
    ; If the absolute difference between the Min and Max
    ; is smaller than the threshold, then just give up !
    
    If Abs(Min - Max) < 0.00000000001
      Min = Max + 10  
    EndIf
    
  Wend
  
  ProcedureReturn Output
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
And the example of use :

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; AUTOMATICALLY GENERATED CODE, DO NOT MODIFY
; UNLESS YOU REALLY, REALLY, REALLY MEAN IT !!
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Code generated by : Dev-Type V4.0.0
; Project name : Iterative Calculation Demo
; File Name : IterativeCalculation - Demo.pb
; File version: 1.0.0
; Programming : OK
; Programmed by : StarBootics
; Date : 20-09-2013
; Last Update : 20-09-2013
; PureBasic code : V5.20 LTS
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

IncludeFile "IterativeCalculation.pb"

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Structure declaration <<<<<

Structure FinesseMax
  
  Thrust.d
  TakeOffWeight.d
  LandingWeight.d
  Sigma.d
  WingArea.d
  TOP.d
  LP.d
  CLMaxTO.d
  CLMaxLA.d
  
EndStructure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The observators <<<<<

Macro GetFinesseMaxThrust(FinesseMaxA)
  
  FinesseMaxA\Thrust
  
EndMacro

Macro GetFinesseMaxTakeOffWeight(FinesseMaxA)
  
  FinesseMaxA\TakeOffWeight
  
EndMacro

Macro GetFinesseMaxLandingWeight(FinesseMaxA)
  
  FinesseMaxA\LandingWeight
  
EndMacro

Macro GetFinesseMaxSigma(FinesseMaxA)
  
  FinesseMaxA\Sigma
  
EndMacro

Macro GetFinesseMaxWingArea(FinesseMaxA)
  
  FinesseMaxA\WingArea
  
EndMacro

Macro GetFinesseMaxTOP(FinesseMaxA)
  
  FinesseMaxA\TOP
  
EndMacro

Macro GetFinesseMaxLP(FinesseMaxA)
  
  FinesseMaxA\LP
  
EndMacro

Macro GetFinesseMaxCLMaxTO(FinesseMaxA)
  
  FinesseMaxA\CLMaxTO
  
EndMacro

Macro GetFinesseMaxCLMaxLA(FinesseMaxA)
  
  FinesseMaxA\CLMaxLA
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The mutators <<<<<

Macro SetFinesseMaxThrust(FinesseMaxA, P_Thrust)
  
  GetFinesseMaxThrust(FinesseMaxA) = P_Thrust
  
EndMacro

Macro SetFinesseMaxTakeOffWeight(FinesseMaxA, P_TakeOffWeight)
  
  GetFinesseMaxTakeOffWeight(FinesseMaxA) = P_TakeOffWeight
  
EndMacro

Macro SetFinesseMaxLandingWeight(FinesseMaxA, P_LandingWeight)
  
  GetFinesseMaxLandingWeight(FinesseMaxA) = P_LandingWeight
  
EndMacro

Macro SetFinesseMaxSigma(FinesseMaxA, P_Sigma)
  
  GetFinesseMaxSigma(FinesseMaxA) = P_Sigma
  
EndMacro

Macro SetFinesseMaxWingArea(FinesseMaxA, P_WingArea)
  
  GetFinesseMaxWingArea(FinesseMaxA) = P_WingArea
  
EndMacro

Macro SetFinesseMaxTOP(FinesseMaxA, P_TOP)
  
  GetFinesseMaxTOP(FinesseMaxA) = P_TOP
  
EndMacro

Macro SetFinesseMaxLP(FinesseMaxA, P_LP)
  
  GetFinesseMaxLP(FinesseMaxA) = P_LP
  
EndMacro

Macro SetFinesseMaxCLMaxTO(FinesseMaxA, P_CLMaxTO)
  
  GetFinesseMaxCLMaxTO(FinesseMaxA) = P_CLMaxTO
  
EndMacro

Macro SetFinesseMaxCLMaxLA(FinesseMaxA, P_CLMaxLA)
  
  GetFinesseMaxCLMaxLA(FinesseMaxA) = P_CLMaxLA
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Update operator <<<<<

Macro UpdateFinesseMax(FinesseMaxA, P_Thrust, P_TakeOffWeight, P_LandingWeight, P_Sigma, P_WingArea, P_TOP, P_LP, P_CLMaxTO, P_CLMaxLA)
  
  SetFinesseMaxThrust(FinesseMaxA, P_Thrust)
  SetFinesseMaxTakeOffWeight(FinesseMaxA, P_TakeOffWeight)
  SetFinesseMaxLandingWeight(FinesseMaxA, P_LandingWeight)
  SetFinesseMaxSigma(FinesseMaxA, P_Sigma)
  SetFinesseMaxWingArea(FinesseMaxA, P_WingArea)
  SetFinesseMaxTOP(FinesseMaxA, P_TOP)
  SetFinesseMaxLP(FinesseMaxA, P_LP)
  SetFinesseMaxCLMaxTO(FinesseMaxA, P_CLMaxTO)
  SetFinesseMaxCLMaxLA(FinesseMaxA, P_CLMaxLA)
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Reset operator <<<<<

Macro ResetFinesseMax(FinesseMaxA)
  
  SetFinesseMaxThrust(FinesseMaxA, 0.0)
  SetFinesseMaxTakeOffWeight(FinesseMaxA, 0.0)
  SetFinesseMaxLandingWeight(FinesseMaxA, 0.0)
  SetFinesseMaxSigma(FinesseMaxA, 0.0)
  SetFinesseMaxWingArea(FinesseMaxA, 0.0)
  SetFinesseMaxTOP(FinesseMaxA, 0.0)
  SetFinesseMaxLP(FinesseMaxA, 0.0)
  SetFinesseMaxCLMaxTO(FinesseMaxA, 0.0)
  SetFinesseMaxCLMaxLA(FinesseMaxA, 0.0)
  
  ; ClearStructure(FinesseMaxA, FinesseMax)
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Debugging macro <<<<<

Macro DebugFinesseMax(FinesseMaxA)
  
  Debug "Thrust : " + StrD(GetFinesseMaxThrust(FinesseMaxA), 6)
  Debug "TakeOffWeight : " + StrD(GetFinesseMaxTakeOffWeight(FinesseMaxA), 6)
  Debug "LandingWeight : " + StrD(GetFinesseMaxLandingWeight(FinesseMaxA), 6)
  Debug "Sigma : " + StrD(GetFinesseMaxSigma(FinesseMaxA), 6)
  Debug "WingArea : " + StrD(GetFinesseMaxWingArea(FinesseMaxA), 6)
  Debug "TOP : " + StrD(GetFinesseMaxTOP(FinesseMaxA), 6)
  Debug "LP : " + StrD(GetFinesseMaxLP(FinesseMaxA), 6)
  Debug "CLMaxTO : " + StrD(GetFinesseMaxCLMaxTO(FinesseMaxA), 6)
  Debug "CLMaxLA : " + StrD(GetFinesseMaxCLMaxLA(FinesseMaxA), 6)
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code generated in : 00.014 seconds (14428.57 lines/second) <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Procedure.d TakeOffDistance(TOP.d, *FinesseMaxA.FinesseMax)
  
  SetFinesseMaxTOP(*FinesseMaxA, TOP)
  SetFinesseMaxCLMaxTO(*FinesseMaxA, (GetFinesseMaxTakeOffWeight(*FinesseMaxA) * GetFinesseMaxTakeOffWeight(*FinesseMaxA)) / (GetFinesseMaxWingArea(*FinesseMaxA) * GetFinesseMaxThrust(*FinesseMaxA) * GetFinesseMaxSigma(*FinesseMaxA) * TOP))
  
  ProcedureReturn 20.9 * TOP + 87.0 * Sqr(TOP * GetFinesseMaxThrust(*FinesseMaxA) / GetFinesseMaxTakeOffWeight(*FinesseMaxA))
EndProcedure

Procedure.d LandingDistance(LP.d, *FinesseMaxA.FinesseMax)
  
  SetFinesseMaxLP(*FinesseMaxA, LP)
  SetFinesseMaxCLMaxLA(*FinesseMaxA, GetFinesseMaxLandingWeight(*FinesseMaxA) / (GetFinesseMaxWingArea(*FinesseMaxA) * GetFinesseMaxSigma(*FinesseMaxA) * LP))
  
  ProcedureReturn 118 * LP + 400
EndProcedure

UpdateFinesseMax(FinesseMax.FinesseMax, 42000.0, 129000.0, 112000.0, 1.0, 1135.0, 0.0, 0.0, 0.0, 0.0)

IterativeCalculation(0.0, 1000.0, 5000.0, @TakeOffDistance(), FinesseMax)
IterativeCalculation(0.0, 1000.0, 5000.0, @LandingDistance(), FinesseMax)
DebugFinesseMax(FinesseMax)

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Regards
StarBootics
The Stone Age did not end due to a shortage of stones !
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Iterative Calculation System

Post by IdeasVacuum »

Well, that works super-fast with your example StarBootics 8)
However, I don't understand the example code, even though I have 20years of aircraft engineering to my name! I think therefore that I will not be the only one to struggle with the concept - Dev-Type code looks tidy but even though the example is short, it is difficult to follow when the concept is not understood.
So, could you make a more 'common place' example please?

Edit: A real World example would be something like this:
Cylinderical water container:
a) Diameter must be minimum 2 * Height
b) Max water level must be 75% of Height
c) Height range 1metre, 1.5, 2, 3, 5

Produce a table consisting of Container Dimensions and Max Water Volume.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Iterative Calculation System

Post by StarBootics »

IdeasVacuum wrote:Well, that works super-fast with your example StarBootics 8)
However, I don't understand the example code, even though I have 20years of aircraft engineering to my name! I think therefore that I will not be the only one to struggle with the concept - Dev-Type code looks tidy but even though the example is short, it is difficult to follow when the concept is not understood.
The equation came from "Design of aircraft Thomas C. Corke 2003" equation 3.3, 3.4 and 3.5.
CL_max_TO = (Wto * Wto) / (WingArea * Thrust * Sigma * TOP)
In order to design your wing (profile, flap, slat), you need to know Finesse is required for Take off. But you need to find the "TOP" (Take Off Parameter) and this is the equation we have :
TakeOffDistance = 20.9 * TOP + 87.0 * sqrt(TOP * Thrust / Wto)
Try to solve this equation for "TOP", I mean an equation look like : TOP = Something, it's very difficult. But what information we have :

TakeOffDistance (We know airports runway length)
Thrust (We have selected your engines and we know the thrust)
Wto (We already have estimated the take off weight)

What the Iterative Calculation will do ? Guessing a value for "TOP" but we know for a fact it's between 0 and 1000, we calculate a TakeOffDistance with the guessed "TOP" then compare it to the TakeOffDistance allowed by the runway length (5000 feet).

In order to have a standard function to fit all cases we put all variables into a Structure (grouping parameters into only one) so almost everything can be calculated. For example you have a cylinder for your example you have a fix volume and height to respect but what about the radius ?

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; AUTOMATICALLY GENERATED CODE, DO NOT MODIFY
; UNLESS YOU REALLY, REALLY, REALLY MEAN IT !!
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Code generated by : Dev-Type V4.0.0
; Project name : Iterative Calculation Demo
; File Name : IterativeCalculation - Demo.pb
; File version: 1.0.0
; Programming : OK
; Programmed by : StarBootics
; Date : 20-09-2013
; Last Update : 20-09-2013
; PureBasic code : V5.20 LTS
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

IncludeFile "IterativeCalculation.pb"

Structure Cylinder
  
  Height.d
  Radius.d
  Volume.d
  Area.d
  
EndStructure 

Procedure.d CylinderVolume(InputRadius.d, *CylinderA.Cylinder)
  
  ; We take a copy of the Radius so when the IterativeCalculation() will give up
  ; we will have the radius we need.
  
  *CylinderA\Radius = InputRadius
  *CylinderA\Volume = #PI * InputRadius * InputRadius * *CylinderA\Height
  *CylinderA\Area = 4 * #PI * InputRadius + 2 * #PI * InputRadius * *CylinderA\Height
  
  ProcedureReturn *CylinderA\Volume
EndProcedure

TargetVolume.d = 785; m³
MinRadius.d = 1.0
MaxRadius.d = 100.0

MyCylinder.Cylinder\Height = 10.0

IterativeCalculation(MinRadius, MaxRadius, TargetVolume, @CylinderVolume(), MyCylinder)

Debug MyCylinder\Height
Debug MyCylinder\Radius
Debug MyCylinder\Volume
Debug MyCylinder\Area

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
I hope it's more clear now.

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Iterative Calculation System

Post by IdeasVacuum »

but what about the radius ?
Diameter must be minimum 2 * Height
:mrgreen:
...and we don't have a target volume, we have specific target heights:
Height range 1metre, 1.5, 2, 3, 5
...the equation is 'unknown' because there is a rule about the maximum water level:
Max water level must be 75% of Height
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Iterative Calculation System

Post by StarBootics »

@IdeasVacuum

What is you are talking about is optimization and the example show an iterative method to find value in some specific cases. It's totally different, than you might not be off topic please. Thank you !

By the way the iteration count depend on the range between the Min and the Max value but it should be under 100 iterations. The Cylinder example, it take 41 iterations, pretty low for an iterative calculation methods.

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Iterative Calculation System

Post by IdeasVacuum »

Hi StarBootics
I don't think I'm off topic really, but it could be a matter of terminology, the term as I understand it's meaning is used by many CAD Systems.
I think your code is along the lines of what is required to solve the unknown val as I proposed. Your cut-down version of my example, solving for the radius given volume and height, just does not need an iterative approach [solution for Diameter: dDia.d = Sqr( 4 * dVol / (#PI * dHeight))]
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Iterative Calculation System

Post by StarBootics »

IdeasVacuum wrote:Your cut-down version of my example, solving for the radius given volume and height, just does not need an iterative approach [solution for Diameter: dDia.d = Sqr( 4 * dVol / (#PI * dHeight))]
As an mechanical engineer I'm well aware about this, a simple equation as cylinder volume don't require an iterative methods. In your first message you have said the given example are very difficult to follow. So I have create a more simple example using the most simple equation I have in mind at that time and you are still not happy with it.

Just in case you have forgotten, I'M TRYING TO DEMONSTRATE AN ITERATIVE METHODS TO SOLVE PROBLEM IN SOME CASES ! The equation the programmer is working with doesn't matter. It is so difficult for you to understand ?

If the equation don't require an iterative method to be solved so don't use an iterative method to solve it. But if it's the case, an example about how it can be done is now available.

That said, It's a little discouraging to see someone reacting like you did.

Anyway this a little update :

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Iterative Calculation System
; File Name : IterativeCalculation.pb
; File version: 1.0.1
; Programming : OK
; Programmed by : StarBootics
; Date : 20-09-2013
; Last Update : 20-09-2013
; PureBasic code : V5.20 LTS
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

#ITERATIVE_CALCULATION_THRESHOLD = 0.00000000001
#ITERATIVE_CALCULATION_ITERATION_MAX = 1000

Prototype.d ProtoCalculator(Input.d, *Pointer)

Procedure.d IterativeCalculation(Min.d, Max.d, Target.d, Calculator.i, *CalculatorExtraParam)
  
  Protected Input.d, Output.d, IternationCounter.l
  
  Calcul.ProtoCalculator = Calculator

  While Min <= Max
    
    Input = (Min + Max) / 2.0
    Output = Calcul(Input, *CalculatorExtraParam)
    
    If Output < Target
      Min = Input
    ElseIf Output > Target
      Max = Input
    EndIf
    
    ; If the absolute difference between the Min and Max
    ; is smaller than the threshold, then just give up !
    
    If Abs(Min - Max) < #ITERATIVE_CALCULATION_THRESHOLD
      Min = Max + 10  
    EndIf
    
    If IternationCounter = #ITERATIVE_CALCULATION_ITERATION_MAX
      Min = Max + 10
    Else
      IternationCounter + 1
    EndIf
    
  Wend

  ProcedureReturn Output
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
StarBootics
The Stone Age did not end due to a shortage of stones !
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Iterative Calculation System

Post by BorisTheOld »

StarBootics wrote:That said, It's a little discouraging to see someone reacting like you did.
All you can do is hope that what you have to say can be of use to someone, and accept, with joy, any positive comments that are given.

Sadly, criticism or complete silence seem to be the normal responses. It happens to me all the time. :)
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Iterative Calculation System

Post by IdeasVacuum »

I am not trying to offend anyone, just asking straight questions because I'm interested in the concept.

I really can't see anything wrong with that, I have answered a lot of questions on this forum - I'd rather have a response showing interest than silence having solved a problem for someone.

StarBootics, you have quoted me out of context - that is not appreciated. Everyone on this forum knows that I am a genuine contributer to discussions and I don't try to discourage or be dismissive of anybody.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
yrreti
Enthusiast
Enthusiast
Posts: 546
Joined: Tue Oct 31, 2006 4:34 am

Re: Iterative Calculation System

Post by yrreti »

StarBootics
Interesting and complex code, which gives an insight of just how complex aircraft engineering is.

But:
That said, It's a little discouraging to see someone reacting like you did.
IdeasVacuum:
Everyone on this forum knows that I am a genuine contributer to discussions and I don't try to discourage or be dismissive of anybody.
IdeasVacuum, I'll sure second that, and always appreciate your contributions to the forum.
yrreti
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Iterative Calculation System

Post by StarBootics »

Hello everyone,

A simple module conversion just for the fun and to see if a Module can drive another Module. The examples are the same.
This iterative method is meant to be use to perform a binary search of unknown value impossible or very difficult isolate inside an equation, like "TOP" in this equation :
TakeOffDistance = 20.9 * TOP + 87.0 * Sqr(TOP * Instance\Thrust / Instance\TakeOffWeight)
5000 = 20.9*TOP + 87.0 * Sqr(TOP * 42000 / 129000)
We iterate left side of the equation by guessing a value for "TOP" until we have 5000 as result. Due to double calculation we end up with a small error, see the example for more detail.

Best regards
StarBootics

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : IterativeCalculation
; File Name : IterativeCalculation - Module.pb
; File version: 2.0.0
; Programming : OK
; Programmed by : StarBootics
; Date : 16-08-2016
; Last Update : 16-08-2016
; PureBasic code : V5.50
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;
; This code is free to be use where ever you like 
; but you use it at your own risk.
;
; The author can in no way be held responsible 
; for data loss, damage or other annoying 
; situations that may occur.
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule IterativeCalculation
  
  Declare.l Counter()
  Declare Reset()
  Declare.d DoIt(Min.d, Max.d, Target.d, Calculator.i, *CalculatorExtraParam)
  
EndDeclareModule

Module IterativeCalculation
  
  #THRESHOLD = 0.00000000001
  #ITERATION_MAX = 1000
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration de la Structure <<<<<
  
  Structure Instance
    
    Counter.l
    
  EndStructure
  
  Global Instance.Instance
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les observateurs <<<<<
  
  Procedure.l Counter()
   
    ProcedureReturn Instance\Counter
  EndProcedure
  
  Procedure Reset()
    
    Instance\Counter = 0
    
  EndProcedure
  
  Prototype.d ProtoCalculator(Input.d, *Pointer)
  
  Procedure.d DoIt(Min.d, Max.d, Target.d, Calculator.i, *CalculatorExtraParam)
    
    Protected Input.d, Output.d
    
    Calcul.ProtoCalculator = Calculator
    
    While Min <= Max
      
      Input = (Min + Max) / 2.0
      Output = Calcul(Input, *CalculatorExtraParam)
      
      If Output < Target
        Min = Input
      ElseIf Output > Target
        Max = Input
      EndIf
      
      ; If the absolute difference between the Min and Max
      ; is smaller than the threshold, then just give up !
      
      If Abs(Min - Max) < #THRESHOLD
        Min = Max + 10  
      EndIf
      
      ; If the iteration count reach the maximum value of 1000
      ; then just give up. It's to avoid endless loop !
      
      If Instance\Counter = #ITERATION_MAX
        Min = Max + 10
      Else
        Instance\Counter + 1
      EndIf
      
    Wend
    
    ProcedureReturn Output
  EndProcedure
  
EndModule

CompilerIf #PB_Compiler_IsMainFile
  
  Structure Cylinder
    
    Height.d
    Radius.d
    Volume.d
    Area.d
    
  EndStructure
  
  Procedure.d CylinderVolume(InputRadius.d, *CylinderA.Cylinder)
    
    ; We take a copy of the Radius so when the IterativeCalculation() will give up
    ; we will have the radius we need.
    
    *CylinderA\Radius = InputRadius
    *CylinderA\Volume = #PI * InputRadius * InputRadius * *CylinderA\Height
    *CylinderA\Area = 4 * #PI * InputRadius + 2 * #PI * InputRadius * *CylinderA\Height
    
    ProcedureReturn *CylinderA\Volume
  EndProcedure
  
  TargetVolume.d = 785; m³
  MinRadius.d = 1.0
  MaxRadius.d = 100.0
  
  MyCylinder.Cylinder\Height = 10.0
  
  IterativeCalculation::DoIt(MinRadius, MaxRadius, TargetVolume, @CylinderVolume(), MyCylinder)
  
  Debug MyCylinder\Height
  Debug MyCylinder\Radius
  Debug MyCylinder\Volume
  Debug MyCylinder\Area
  Debug IterativeCalculation::Counter()
  IterativeCalculation::Reset()
  
  Debug ""
  Debug "; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
  Debug ""
  
  DeclareModule FinesseMax
    
    Declare.d GetTOP()
    Declare.d GetLP()
    Declare Update(P_Thrust.d, P_TakeOffWeight.d, P_LandingWeight.d, P_Sigma.d, P_WingArea.d, P_TOP.d, P_LP.d, P_CLMaxTO.d, P_CLMaxLA.d)
    Declare.d TakeOffDistance(TOP.d, *Extra = #Null)
    Declare.d LandingDistance(LP.d, *Extra = #Null)
    
    CompilerIf #PB_Compiler_Debugger
      Declare Debugging()
    CompilerEndIf
    
  EndDeclareModule
  
  Module FinesseMax
    
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    ; <<<<< Déclaration de la Structure <<<<<
    
    Structure Instance
      
      Thrust.d
      TakeOffWeight.d
      LandingWeight.d
      Sigma.d
      WingArea.d
      TOP.d
      LP.d
      CLMaxTO.d
      CLMaxLA.d
      
    EndStructure
    
    Global Instance.Instance
    
    
    Procedure.d GetTOP()
      
      ProcedureReturn Instance\TOP
    EndProcedure
    
    Procedure.d GetLP()
      
      ProcedureReturn Instance\LP
    EndProcedure
    
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    ; <<<<< L'opérateur Update <<<<<
    
    Procedure Update(P_Thrust.d, P_TakeOffWeight.d, P_LandingWeight.d, P_Sigma.d, P_WingArea.d, P_TOP.d, P_LP.d, P_CLMaxTO.d, P_CLMaxLA.d)
      
      Instance\Thrust = P_Thrust
      Instance\TakeOffWeight = P_TakeOffWeight
      Instance\LandingWeight = P_LandingWeight
      Instance\Sigma = P_Sigma
      Instance\WingArea = P_WingArea
      Instance\TOP = P_TOP
      Instance\LP = P_LP
      Instance\CLMaxTO = P_CLMaxTO
      Instance\CLMaxLA = P_CLMaxLA
      
    EndProcedure
    
    Procedure.d TakeOffDistance(TOP.d, *Extra = #Null)
      
      Instance\TOP = TOP
      Instance\CLMaxTO = (Instance\TakeOffWeight * Instance\TakeOffWeight) / (Instance\WingArea * Instance\Thrust * Instance\Sigma * Instance\TOP)
      
      ProcedureReturn 20.9 * TOP + 87.0 * Sqr(TOP * Instance\Thrust / Instance\TakeOffWeight)
    EndProcedure
    
    Procedure.d LandingDistance(LP.d, *Extra = #Null)
      
      Instance\LP = LP
      Instance\CLMaxLA = Instance\LandingWeight / (Instance\WingArea * Instance\Sigma * LP)
      
      ProcedureReturn 118 * LP + 400
    EndProcedure
    
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    ; <<<<< L'opérateur de Deboggage <<<<<
    
    CompilerIf #PB_Compiler_Debugger
      
      Procedure Debugging()
        
        Debug Instance\Thrust
        Debug Instance\TakeOffWeight
        Debug Instance\LandingWeight
        Debug Instance\Sigma
        Debug Instance\WingArea
        Debug Instance\TOP
        Debug Instance\LP
        Debug Instance\CLMaxTO
        Debug Instance\CLMaxLA
        
      EndProcedure
      
    CompilerEndIf
    
  EndModule
  
  
  FinesseMax::Update(42000.0, 129000.0, 112000.0, 1.0, 1135.0, 0.0, 0.0, 0.0, 0.0)
  
  IterativeCalculation::DoIt(0.0, 1000.0, 5000.0, FinesseMax::@TakeOffDistance(), #Null)
  TOP_Counter = IterativeCalculation::Counter()
  IterativeCalculation::Reset()
  
  IterativeCalculation::DoIt(0.0, 1000.0, 5000.0, FinesseMax::@LandingDistance(), #Null)
  LP_Counter = IterativeCalculation::Counter()
  IterativeCalculation::Reset()
  
  CompilerIf #PB_Compiler_Debugger
    FinesseMax::Debugging()
  CompilerEndIf

  Debug TOP_Counter
  Debug LP_Counter
  
  Debug FinesseMax::TakeOffDistance(FinesseMax::GetTOP()) ; Let's see how far we are to the real takeoff distance of 5000 ft
  Debug FinesseMax::LandingDistance(FinesseMax::GetLP()) ; Let's see how far we are to the real landing distance of 5000 ft
  
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
The Stone Age did not end due to a shortage of stones !
Post Reply