Перебор столбцов в матрице с использованием трубопровода - PullRequest
0 голосов
/ 22 мая 2018

Я пытаюсь разделить матрицу по ее последней строке (каждый столбец по своему последнему элементу - так называемым однородным координатам), а затем вернуть подматрицу, содержащую все, кроме этой последней строки.Примерно так в Matlab:

normx = bsxfun(@rdivide,A,A(end,:));
output = normx(1:end-1,:);

Поскольку я новичок в F #, я не совсем уверен ни в чем, но я попробовал это:

let hnorm(A:Matrix<double>) = 
    let partialResult = A |> Matrix.iterCols (fun col -> col/col.[col.Count-1])
    partialResult.Rows(0,3)

, но я получил " Ожидается, что это выражение будет иметь тип 'unit', но здесь есть ошибка типа 'Vector '"в лямбда-выражении.

И я не понимаю, что не так с примерамивроде

let result = [2;4;6] |> List.map (fun x -> x * x * x)

хорошо работает.

Может кто-нибудь объяснить, как это можно сделать, потому что я думаю, что мне не хватает некоторых основ или неправильно их понял.

Спасибо!

1 Ответ

0 голосов
/ 22 мая 2018

Если вы посмотрите на подпись Matrix.iterCols (наведите указатель мыши на нее в вашей IDE), вы увидите, что аргумент, который она принимает, является функцией Vector<'a> -> unit, то есть это функция, которая принимает Vector<'a>в качестве аргумента и возвращает unit.

Ваша функция fun col -> col/col.[col.Count-1], с другой стороны, фактически возвращает Vector<_>, потому что это результат деления там.Поскольку Vector<_> не является unit, компилятор жалуется: "ожидалось, что это значение будет иметь тип 'unit', но здесь имеет тип Vector <>" .Это то, что компилятор пытается вам сказать.

В соответствии с соглашением F #, функции с именем iter* обычно означают "пройти через эту последовательность и создать некоторый побочный эффект для каждого элемента" , где побочным эффектом может быть что-то вроде печати на экране или изменения ячейки памяти и т. Д. Вот почему аргумент iterCols должен возвращать unit: его единственная цель - создать побочный эффект, он не должен возвращать никаких полезных значений.

Но то, что вы пытаетесь сделать, это , а не для получения побочного эффекта.Вы пытаетесь создать еще один Matrix, в котором все столбцы разделены на последний элемент.Эту операцию преобразования контейнера с применением некоторой функции к каждому из его элементов традиционно называют «картой» в функциональном программировании.И вот: на самом деле есть функция Matrix.mapCols, которая делает именно то, что вы ожидаете:

let partialResult = A |> Matrix.mapCols (fun idx col -> col/col.[col.Count-1])

Обратите внимание, что аргумент mapCols должен принимать два параметра вместо одного:первый - это индекс столбца, а второй - сам столбец.

...