Added a new Solve overload to provide more flexibility/efficiency

The new Solve overload allows the caller to pass in any strange shaped
data structure along with action methods to access the rows and columns
within this data structure. This means callers no longer have to convert
their data structures into a 2D matrix. The old Solve overloads now call
into the new overload.