2014-12-19 8 views
0

В this question я спросил, как выполнить аналогичную операцию с помощью PowerPack. Я решил использовать MathNet вместо этого, поскольку он предназначен для .Net в целом, а не только для F #.Как сравнить элементы матрицы в Math.Net в F #

Мне нужна функция, которая принимает 2 матрицы и выводит процент соглашения. Значения в матрицах равны либо 1,0, либо -1,0. По-видимому, матрицы типа Matrix (int) не поддерживаются.

У меня есть функция, которая выполняет это, но я подозреваю, что есть более прямой путь для этого, предпочтительно используя функциональность класса Matrix.

Это то, что я получил:

let percentageTheSame (a:Matrix<float>) (b:Matrix<float>) = 
    let seqA = a |> Matrix.toSeq 
    let seqB = b |> Matrix.toSeq 
    let sames = Seq.map2 (fun a b -> (a,b)) seqA seqB |> Seq.filter (fun (a, b) -> a = b) 
    float(sames.Count())/float(seqA.Count()) 
+0

И почему что у вас недостаточно? – scrwtp

+0

Только очевидное улучшение заключается в использовании 'Seq.zip' вместо' map2' –

+0

Шахта не достаточно хороша, потому что ей приходится прибегать к использованию класса коллекции без матрицы. Густаво прибил его. –

ответ

2

Вот решение аналогично тому, с помощью PowerPack:

let percentageTheSame (a:Matrix<float>) (b:Matrix<float>) = 
    let z,t = Matrix.fold (fun (z,t) e -> (if e = 0. then z+1 else z), t+1) (0,0) (a-b) 
    float z/float t 

Или с помощью foldi, вместо вычитания матриц, может быть более эффективным для больших матриц, так как не требуется выделять промежуточную матрицу:

let percentageTheSame (a:Matrix<float>) (b:Matrix<float>) = 
    let z,t = 
    Matrix.foldi (fun i j (z,t) e -> (if e = b.[i,j] then z+1 else z), t+1) (0,0) a 
    float z/float t 
+0

Хороший материал, спасибо! –

+0

Интересно, что не существует никакой документации по функции foldi для класса матрицы: http://numerics.mathdotnet.com/api/MathNet.Numerics.LinearAlgebra/Matrix%601.htm –

+0

Может быть, это только в F # компонента MathNet. – Gustavo