function [c,ceq] = csp_advisor(TotalmassFlow)
The constraint function is passed the current value of all of the variables -- what you refer to as para in your main function. The constraint mechanism has no idea that one of the elements of para is acting as TotalMassFlow . You would have to extract TotalMassFlow out of para, such as
function [c,ceq] = csp_advisor(para)
TotalMassFlow = para(9);
c = -TotalmassFlow + 9.36e3;
ceq = ;
c = -TotalmassFlow + 9.36e3;
That is just an upper or lower bound on the element that represents TotalmassFlow. Do not implement upper or lower bounds through the nonlinear constraints: implement them through the lb and ub positions.
TotalmassFlow = sum(massFlow);
Oh, wait, TotalmassFlow is a calculated value, not one of the variables of optimization?? Calculated values are never passed into the nonlinear constraint function. The constraint function is passed only the current variables of optimization, para.
There is something crucial that you need to understand:
- The optimization routines do not call the nonlinear constraint function after every call to the objective function. If the previous location met constraints and the current location has a higher objective value than the old one, then regardless of whether the current location meets constraints or not, it is not going to be better than the old location. Also, the optimizers that estimate jacobians or hessians do not call the nonlinear constraints for the first several calls, while they gather enough information to estimate the jacobians.
- The optimization routines may call the nonlinear constraint function a number of times in a row without calling the objective function, especially if they have not yet found any point that is within constraints. Constraint functions are typically lower cost than the objective function, so it can make sense to find out whether a point is within constraints first before bothering to calculate the cost associated with the point
- Putting these together: when the nonlinear constraint function is called, you cannot count on it being called immediately after the call to the objective function with the same inputs, and when the objective function is called, you cannot count on it being called immediately after the call to the nonlinear constraint function with the same inputs. Therefore, mechanisms that work by storing the "latest" result from one for use in the other are not certain to work properly
- Since both your nonlinear constraint and objective function need to run the external model to build the values to calculate TotalmassFlow, you should put those calculations into a separate routine that you call from both functions
It appears likely that the calculation of TotalmassFlow is "expensive" in that it needs to activate an external program through a .NET assembly. You would like to avoid having to recalculate with the same parameters. But as described above, you cannot count on just saving the latest results from one for use in the other.
What to do for efficiency then? The answer is that when you put the calculations into a seperate routine, that you should memoize() the routine. memoize() is a layer that automatically builds a cache (that you can adjust the size of) on top of a function call, so that when it detects that the function is being calculated with the same arguments, it just pulls out the previous value instead of re-running the routine. Then it does not matter whether the separate function that invokes the external model got called first from the nonlinear constraints function or the objective function: the cache will be consulted and the result will be recalled either way. (You probably want the cache size to be larger than the population size.) The two routines do need to share the memoized handle, so you should either use a shared variable or else memoize first and pass that as an extra parameter into both the objective function and the nonlinear constraint function. http://www.mathworks.com/help/matlab/math/parameterizing-functions.html