In this post we introduce some utility methods to make it easier to work with arrays in Solver Foundation programs. Most real models involve either input parameters or output decision variables that involve collections. For example, in an investment portfolio optimization model we may have an input parameter that represents the mean return for each potential investment in the portfolio. In such a case the mean return may be stored in an array of doubles. In the Solver Foundation model, we’d define a Set for the investment types, and then define a parameter “meanReturn” that is indexed by that set.  Then we would call SetBinding to associate the array with the Parameter. But have a look at the signature for Parameter.SetBinding:

void SetBinding<T>(IEnumerable<T> binding, string valueField, params string[] indexFields);

It’s not at all obvious what to do! The first entry should obviously be the array (since arrays implement IEnumerable), but what should we fill in for the “valueField”? If I had an array of objects, I would fill in the name for the property on the object that returned the mean return. But in this case I have an array of doubles. One way to handle this problem would be to transform the array of doubles into an array of objects with the right type. But it’s a pain to do this each time I want to bind to an array. So why not write some utility methods that automatically do this work?  Here goes:

    /// <summary>Bind an indexed parameter to an IEnumerable of values.
    /// </summary>
    public static void SetBinding(this Parameter parameter, IEnumerable<double> data) {
      parameter.SetBinding(ToIEnumerable(data), "Value", "Key");
    }

    private static IEnumerable<KeyValuePair<int, T>> ToIEnumerable<T>(IEnumerable<T> vector) {
      return vector.Select((d, index) => new KeyValuePair<int, T>(index, d));
    }

I have added a method called SetBinding. The “this” before the first argument means that SetBinding is an extension method, which means we can call it as if it were a member of the Parameter class. The body of the method calls a utility function called ToIEnumerable. ToIEnumerable simply does a LINQ Select on the data, transforming it into an IEnumerable of (key, value) pairs. Now we’ve got what we want! We pass it into SetBinding, specifying “Value” and “Key” for the value and index fields, respectively. 

Notice that I can do the same thing for scalar parameters (parameters with 0 indexes) and “matrix parameters” (parameters with 2 indexes). A similar issue exists for getting results. Sometimes I just want to get an array of doubles corresponding to the values for a 1-indexed Decision. Using LINQ it’s easy to pull the values out of the Decision.GetValues method and push them into an array.  I can wrap all of this stuff into a new class – here it is. (Note that some of the standard argument checking has been left out for brevity):

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.SolverFoundation.Common;
using Microsoft.SolverFoundation.Services;

namespace SolverFoundation.Samples {
  /// <summary>Helper methods for Parameter and Decision data binding.
  /// </summary>
  public static class BindingUtilities {

    /// <summary>Bind a parameter to a scalar value.
    /// </summary>
    public static void SetBinding(this Parameter parameter, double data) {
      parameter.SetBinding(ToIEnumerable(data), "Value");
    }

    /// <summary>Bind an indexed parameter to an IEnumerable of values.
    /// </summary>
    public static void SetBinding(this Parameter parameter, IEnumerable<double> data) {
      parameter.SetBinding(ToIEnumerable(data), "Value", "Key");
    }

    /// <summary>Bind an indexed parameter to a table.
    /// </summary>
    public static void SetBinding(this Parameter parameter, IEnumerable<IEnumerable<double>> data) {
      parameter.SetBinding(ToIEnumerable(data), "Item3", "Item1", "Item2");
    }

    /// <summary>Gets the values for a decision with one index Set.
    /// </summary>
    /// <returns>An IEnumerable containing the values.</returns>
    /// <remarks>The values are returned ordered by index.</remarks>
    public static IEnumerable<double> GetValuesByIndex(this Decision decision) {
      // GetValues returns the values in order of index --> no need to sort.
      return decision.GetValues().Select(r => Convert.ToDouble(r[0]));
    }

    /// <summary>Gets the values for a decision with two index Sets.
    /// </summary>
    /// <returns>An IEnumerable containing the values, grouped by the first index.</returns>
    /// <remarks>The values are returned ordered by index.</remarks>
    public static IEnumerable<IEnumerable<double>> GetValuesByFirstIndex(this Decision decision) {
      // GetValues returns the values in order of index --> no need to sort.
      return decision.GetValues().GroupBy(r => r[1]).Select(g => g.Select(r => Convert.ToDouble(r[0])));
    }

    private static IEnumerable<KeyValuePair<int, T>> ToIEnumerable<T>(T value) {
      return new KeyValuePair<int, T>[] { new KeyValuePair<int, T>(0, value) };
    }

    private static IEnumerable<KeyValuePair<int, T>> ToIEnumerable<T>(IEnumerable<T> vector) {
      return vector.Select((d, index) => new KeyValuePair<int, T>(index, d));
    }

    private static IEnumerable<Tuple<int, int, T>> ToIEnumerable<T>(IEnumerable<IEnumerable<T>> matrix) {
      var m = matrix.Select((row, i) => row.Select((cell, j) => new Tuple<int, int, T>(i, j, cell)));
      var cells = from cell in m.SelectMany(c => c) select cell;
      return cells;
    }
  }
}

Once I have this class, life is much simpler whenever I want to bind parameters to arrays (or lists). For example, here is a C# program that builds and solves the portfolio optimization model I introduced earlier. I have obnoxiously put four lines in large bold type to show you where the utility functions are called. Very simple!

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SolverFoundation.Services;

namespace SolverFoundation.Samples {
  public class QuadraticPortfolioSample {
    public static double[] Solve(double required, double[] meanReturn, double[][] covar) {
      SolverContext context = SolverContext.GetContext();
      Model model = context.CreateModel();

      Set I = new Set(Domain.Any, "I");
      Set J = new Set(Domain.Any, "J");

      Parameter requiredReturn = new Parameter(Domain.Real, "RequiredReturn");
      Parameter mean = new Parameter(Domain.Real, "Mean", I);
      Parameter cov = new Parameter(Domain.Real, "Cov", I, J);
      model.AddParameters(requiredReturn, mean, cov);

      Decision allocation = new Decision(Domain.RealRange(0, 1), "Allocation", I);
      Decision portfolioYield = new Decision(Domain.RealNonnegative, "Yield");
      model.AddDecisions(allocation, portfolioYield);

      model.AddConstraint("c1", (portfolioYield >= requiredReturn));
      model.AddConstraint("c2", (Model.Sum(Model.ForEach(I, i => allocation[i])) == 1));
      model.AddConstraint("c3", (Model.Sum(Model.ForEach(I, i => (mean[i] * allocation[i]))) == portfolioYield));
      model.AddGoal("Variance", GoalKind.Minimize,
        Model.Sum(Model.ForEach(I, i => Model.ForEach(J, j => Model.Product(cov[i, j], allocation[i], allocation[j]))))
        );

      requiredReturn.SetBinding(required);
      mean.SetBinding(meanReturn);
      cov.SetBinding(covar);

      var solution = context.Solve();
      return allocation.GetValuesByIndex().ToArray();
    }
  }
}

Now it’s a breeze to call this method to solve portfolio optimization models. Look:

    private static void TryIt() {
      QuadraticPortfolioSample m = new QuadraticPortfolioSample();
      double requiredReturn = 0.06;
      double[] meanReturn = { .1322, .0824, .0903, .0873, .0629, .0910 };
      var covar = new double[][] {
        new double[] {0.006650561,    0.000261280,    0.000217891,    0.003089108,    0.000137570,    0.002071282},
        new double[] {0.000261280,    0.000062715,    0.000048178,    0.000326722,    -0.000043052,    0.000131168},
        new double[] {0.000217891,    0.000048178,    0.000037676,    0.000321380,    -0.000031673,    0.000118690},
        new double[] {0.003089108,    0.000326722,    0.000321380,    0.014783517,    0.001100947,    0.003924335},
        new double[] {0.000137570,    -0.000043052,    -0.000031673,    0.001100947,    0.000372023,    0.000307163},
        new double[] {0.002071282,    0.000131168,    0.000118690,    0.003924335,    0.000307163,    0.001310528}
      };
      // the following line is awesome in its simplicity.
      double[] allocation = QuadraticPortfolioSample.Solve(requiredReturn, meanReturn, covar);
      for (int i = 0; i < allocation.Length; i++) {
        Console.WriteLine("{0}\t{1}", i, allocation[i].ToString("P"));
      }
    }

Let us know if you find these utility methods useful!