title: How can I emulate Microsoft Excel's Solver functionality (GRG Nonlinear) in C#?
body: <p>I have a non-linear optimization problem with constraints. It can be solved in Microsoft Excel with the Solver add-in, but I am having trouble replicating that in C#.</p>
  
  <p>My problem is shown in the <a href="https://docs.google.com/spreadsheet/ccc?key=0Ao_JJoIxovnBdEYydWwyUlRjT3VtWlBfaV9NaHVBX1E" rel="noreferrer">following spreadsheet</a>. I am solving the classic <em>A x = b</em> problem but with the caveat that all components of <em>x</em> must be non-negative. So instead of using standard linear algebra I use Solver with the non-negative constraint, minimizing the sum of the squared differences, and get a reasonable solution. I have tried to replicate this in C# using either <a href="http://msdn.microsoft.com/en-us/library/ff524509(v=vs.93)" rel="noreferrer">Microsoft Solver Foundation</a> or <a href="http://www.solver.com/sdkplatform.htm" rel="noreferrer">Solver SDK</a>. However I can't seem to get anywhere with them because with MSF I can't figure out how to define the goal and with Solver SDK I always get back status "optimal" and a solution of all 0s which is definitely not even a local minimum.</p>
  
  <p>Here is my code for Solver SDK:</p>
  
  <pre><code>static double[][] A = new double[][] { new double[] { 1, 0, 0, 0, 0 }, new double[] { 0.760652602, 1, 0, 0, 0 }, new double[] { 0.373419404, 0.760537565, 1, 0, 0 }, new double[] { 0.136996731, 0.373331934, 0.760422587, 1, 0 }, new double[] { 0.040625222, 0.136953801, 0.373244464, 0.76030755, 1 } };
  static double[][] b = new double[][] { new double[] { 2017159 }, new double[] { 1609660 }, new double[] { 837732.8125 }, new double[] { 330977.3125 }, new double[] { 87528.38281 } };
  
  static void Main(string[] args)
  {
      using(Problem problem = new Problem(Solver_Type.Minimize, 5, 0))
      {
          problem.VarDecision.LowerBound.Array = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0 };
          problem.VarDecision.UpperBound.Array = new double[] { Constants.PINF, Constants.PINF, Constants.PINF, Constants.PINF, Constants.PINF };
  
          problem.Evaluators[Eval_Type.Function].OnEvaluate += new EvaluateEventHandler(SumOfSquaredErrors);
  
          problem.ProblemType = Problem_Type.OptNLP;
  
          problem.Solver.Optimize();
  
          Optimize_Status status = problem.Solver.OptimizeStatus;
  
          Console.WriteLine(status.ToString());
          foreach(double x in problem.VarDecision.FinalValue.Array)
          {
              Console.WriteLine(x);
          }
      }
  }
  
  static Engine_Action SumOfSquaredErrors(Evaluator evaluator)
  {
      double[][] x = new double[evaluator.Problem.Variables[0].Value.Array.Length][];
      for(int i = 0; i &lt; x.Length; i++)
      {
          x[i] = new double[1] { evaluator.Problem.Variables[0].Value.Array[i] };
      }
  
      double[][] b_calculated = MatrixMultiply(A, x);
  
      double sum_sq = 0.0;
      for(int i = 0; i &lt; b_calculated.Length; i++)
      {
          sum_sq += Math.Pow(b_calculated[i][0] - b[i][0], 2);
      }
      evaluator.Problem.FcnObjective.Value[0] = sum_sq;
  
      return Engine_Action.Continue;
  }
  
  static double[][] MatrixMultiply(double[][] left, double[][] right)
  {
      if(left[0].Length != right.Length)
      {
          throw new ArgumentException();
      }
  
      double[][] sum = new double[left.Length][];
      for(int i = sum.GetLowerBound(0); i &lt;= sum.GetUpperBound(0); i++)
      {
          sum[i] = new double[right[i].Length];
      }
  
      for(int i = 0; i &lt; sum.Length; i++)
      {
          for(int j = 0; j &lt; sum[0].Length; j++)
          {
              for(int k = 0; k &lt; right.Length; k++)
              {
                  sum[i][j] += left[i][k] * right[k][j];
              }
          }
      }
  
      return sum;
  }
  </code></pre>
  
  <p>I don't have any code for Microsoft Solver Foundation because I don't think the goal function can be written in a single line and it doesn't allow for delegates like Solver SDK does.</p>