如何编写函数 vmProduct,它将大小为 n 的行向量与具有 n 行和 m 列的矩阵相乘,以在 SML 中生成大小为 m 的向量

How to Write a function vmProduct that multiple a row vector of size n with a matrix with n rows and m columns to produce a vector of size m in SML

如何编写一个函数,将大小为 n 的行向量与 具有 n 行和 m 列的矩阵以生成大小为 m 的向量。为了 例如,([1,2,3], [[1,1], [2,1], [3,1]]) 应该 return [14, 6].

我相信这两个功能可以利用:


fun vectorAdd(nil, _) = nil
  | vectorAdd(_, nil) = nil
  | vectorAdd(a1::first_list, a2::second_list) = 
    (a1 + a2) :: vectorAdd(first_list, second_list);

val q1_answer = vectorAdd([1,2,3], [4,5,2]);

fun svProduct(x, y) = 
  map (fn (item) => item * x) y;

val q2_answer = svProduct(2, [1,2,3]);

让我们先解决一些问题:

exception UnmatchedLengths;

fun transpose([]) = []
  | transpose([[]]) = []
  | transpose([]::_) = []
  | transpose(lst) = List.map List.hd lst :: transpose(List.map List.tl lst);

fun map2(_, [], []) = []
  | map2(_, [], _) = raise UnmatchedLengths
  | map2(_, _, []) = raise UnmatchedLengths
  | map2(f, x::xs, y::ys) = f(x, y) :: map2(f, xs, ys);

fun sum lst = 
  List.foldl op+ 0 lst;

transpose 函数获取列表的列表并将其转置。因此,在您的示例中,[[1,2,3], [[1,1], [2,1], [3,1]] 变为 [[1, 2, 3], [1, 1, 1]].

map2 函数接受一个作用于两个列表的函数,并将一个函数映射到它们对应的组件上。例如

map2(op+, [1, 2, 3], [4, 5, 6])

计算结果为:

[5, 7, 9]

sum非常不言自明,使用list.foldlop+对整数列表求和。

综合起来

将它们放在一起,我们可以创建一个函数 m 来执行您要实现的计算:

fun m(v, ma) = 
  let
    val t = transpose(ma)
    val combos = List.map (fn mi => (v, mi)) t
    val products = List.map (fn (a, b) => map2(op*, a, b)) combos 
  in
    List.map sum products
  end;

首先我们转置矩阵。然后我们创建一个向量元组列表和转置矩阵中的每一行。在您的示例中,我们现在有 [([1, 2, 3], [1, 2, 3]), ([1, 2, 3], [1, 1, 1])].

接下来我们映射这些组合,使用 map2 进行乘法运算。

在您的示例中,我们现在得到 [[1, 4, 9], [1, 2, 3]]

最后一步只是将 sum 映射到其中的每一个,这样我们就可以得到 [14, 6]