title: Can the genetic-algorithm in Matlab pass a second return value from the fitness-function to the constraints?
body: <p>I am simulating a batch evaporator in Matlab. The genetic algorithm varies several starting variables x (such as size, max. mass of working fluid, the overall number of evaporators used ...) and the goal is to maximize the efficiency. So my function <code>evaporator(x)</code> returns the negative efficiency which is minimized by the algorithm.<br>
  Besides the efficiency, there are several other values calculated. One is the duration of the simulated cycle (NOT the runtime of the calculation itself!). As a constraint, the duration of the whole evaporation cycle should, depending on the number of evaporators, not be to short (e.g. if three evaporators are used, the whole cycle should take at least 3*5s = 15s).<br>
  I know that I can easily use the nonlinear constraints option of ga (<code>nonlcon</code>). In this case I would just have to do the same calculations from <code>evaporator(x)</code> again, but return the calculated duration this time. The problem is, that I have to call an external DLL several thousand times per run and the calculations become really slow. Therefore I really want to avoid running all the calculations twice.<br>
  Is it somehow possible, that <code>evaporator(x)</code> returns both the negative efficiency and the duration at the same time? ga should then minimize the negative efficiency and evaluate the duration regarding the constraints. I thought about nesting the <code>evaporator(x)</code> inside an anonymous function, but I think my function still has to be called twice then?  </p>
  
  <p>I had good experience with the Multiobjective Optimization of the efficiency and the duration at the same time, but unfortunately the <code>gamultiobj</code> algorithm cannot handle integer variables.  </p>
  
  <p>At the moment I am using a penalty function on short durations inside <code>evaporator(x)</code>, but I think, that the constraints handling of the ga algorithm would be better than this.  </p>
  
  <p><strong>Edit:</strong>
  So it got a bit more complicated, but in the end it is working:</p>
  
  <pre><code>function [ returnValue ] = switchHXoutput( requestedCase, inputs )
  %SwitchHXoutput returns fitness value or duration depending on requested
  %case
  
  persistent fitnessValue duration oldInputs;
  
  if isempty(oldInputs)
      oldInputs = {}; %initialize oldInputs as cell
  end
  
  
  [isAllreadyCalculated, iOldInput] =...
  ismember(cell2mat(inputs), cell2mat([oldInputs{:}]), 'rows'); 
  
  if isempty(oldInputs) || ~isAllreadyCalculated
      [fitnessValue(end+1), duration(end+1)] = lengthyCalculation(inputs); %add current results to persistent array
      oldInputs(end+1) = {inputs}; %add current inputs to persistent array
      returnValue = [fitnessValue(end), duration(end)];
  else
      returnValue = [fitnessValue(iOldInput), duration(iOldInput)]; % return old values
  end
  
  if strcmp(requestedCase, 'FitnessValue')
      returnValue = returnValue(1);
  elseif strcmp(requestedCase, 'duration')
      returnValue = returnValue(2);
  else
      error('MyApp:SelectOutput','Requested case not supported')
  end
  
  end %function
  </code></pre>
  
  <p>I know that a growing cell array isn't exactly fast. But as my <code>lengthyCalculation</code> takes about 2 minutes for each call I am still saving a lot of time. Furthermore the best individuals of each generation are used again in the next generation. So in this case the saved values can be used instead of recalculating them again. The code works also fine with parallel computation. Normally the fitness value and the duration are calculated by the same worker. Only for following generations the results can be on another worker.</p>