0

Using Math.Net numerics, I would like to do a task:

Fold through each column, and multiply that column's value by the index of my vector. The problem is, none of the folding functions yield a counter...and counting within the folding functions is problematic...and for loops are death for this kind of thing...

Anyhow, ideally I would do something like:

points.FoldByColumn(fun i acc x -> acc <- acc + x * coefficients_array.[i])
|> Array.map(fun x -> x + coefficients_array.[coefficients_array.length-1])

(this is written in F# syntax).

The statement is exactly equivalent to this statement in Python using Numpy broadcasting:

return (self.model_coefs[:-1] * points).sum(axis = 1) + self.model_coefs[-1]

What it is doing is multiplying a set of points by their linear regression coefficients, and turning them into a single predicted point.

(Or am I really just crazy to try to do this stuff on .NET??)

TylerH
  • 20,799
  • 66
  • 75
  • 101
Chris
  • 28,822
  • 27
  • 83
  • 158
  • Real mathematicians use Matlab for this processing. You can convert a matlab script into a dll (utility comes with matlab) and then call the dll from a C# application. We do it all the time. – jdweng Dec 06 '15 at 03:52
  • Not sure what you mean by "counter", but maybe `mapi` will work for you? – Fyodor Soikin Dec 06 '15 at 04:38
  • @jdweng 'Real mathematicians' must really hate type safety, reliability and concise integration with the rest of their .NET software platform then. Math.NET is quite a nicely designed library which supports idiomatic usage in both F# and C# and there are plenty of legitimate reasons to use it over a MATLAB dll. You should use the right tool for the right job. – TheInnerLight Dec 06 '15 at 10:57
  • You can't beat the speed performance of matlab and the excellent plotting capability. Using a dll gives best of both worlds. – jdweng Dec 06 '15 at 16:30
  • @jdweng You can use an MKL provider for Math.NET which is extremely high performance. My understanding is that MATLAB also makes uses of MKL so there is no reason to expect superior performance. Don't get me wrong, I'm not disputing the usefulness of MATLAB especially for rapid prototyping/research but when I need more guarantees about correctness, particularly in a production environment, I'd much rather be using a strongly-typed language like with unit of measure support (like F#). – TheInnerLight Dec 06 '15 at 18:30

2 Answers2

1

There is indeed an indexed fold-by-column function in the F# extensions (MathNet.Numerics.FSharp package). I don't understand why you'd assign some mutable variable within your fold lambda, but assume what you're looking for is something along the lines of this:

let points = DenseMatrix.randomStandard<float> 10 3 // 10 points (3 dimensions)
let coefficients_array = [| 1.1; 2.1; -2.0; 4.1 |] // 4 coefficients (intercept at tail)

let m = points.RowCount // point count
let n = points.ColumnCount // number of coefficients minus intercept (=coefficients_array.Length-1)

let a =
    points
    |> Matrix.foldiCols (fun i acc v -> acc + v*coefficients_array.[i]) (DenseVector.zero m)
    |> Vector.map (fun x -> x + coefficients_array.[n])

However, what this really does is just a matrix vector multiplication. So why not just write it as follows?

// Split coefficients_array into coefficients and intercept
let coefficients = DenseVector.init n (fun i -> coefficients_array.[i])
let intercept = coefficients_array.[n]

let b = points * coefficients + intercept
Christoph Rüegg
  • 4,626
  • 1
  • 20
  • 34
0

On reading your question a second time, it seems you're looking for something more along the lines of the following, where you have one coefficient per point, not per dimension (plus an intercept):

let n = 3 // 3 columns
let m = 10 // 10 points
let points = DenseMatrix.randomStandard<float> m n

// one coefficient for each point, plus one intercept (11 total)
let coefficients = DenseVector.randomStandard<float> (m+1)

let c = coefficients.[0..m-1] * points + coefficients.[m]
Christoph Rüegg
  • 4,626
  • 1
  • 20
  • 34