Как добавить 2 матрицы вместе в OCAML без модулей? - PullRequest
0 голосов
/ 23 октября 2019

Я сделал функцию , которая проверяет действительную матрицу , функцию , которая находит длину списка и функция , которая устанавливает длину строки и количество столбцов в матрице. Что мне нужно знать, это как написать функцию , которая добавляет две матрицы вместе БЕЗ МОДУЛЕЙ . Я покажу выполненные функции ниже :

(* declaration of types intseq and intmatrix *)
type intseq = int list;;

type intmatrix = IM of intseq list;;

let getbody (IM x) = x;;

(* function getbody to retrieve the body of the intmatrix which is of type intseq list *)

let rec length: 'a list -> int =
  fun xs ->
  match xs with
    [] -> 0
  | (x::rest) -> 1 + length rest;;

(* test whether a list of lists of integers represents a matrix. 
   The length of each row should be equal.*)
let rec ismatrix x =

  match x with
    | IM([]) -> true
    | IM([[]]) -> true
    | IM([_]) -> true
    | IM(x::x2::rest) -> if (length x <> length x2)
        then false
        else ismatrix (IM(x2::rest));;

(* function matrixshape takes the matrix, and calculates the number of
   columns and rows *)
let rec matrixshape x =
  match x with
    | IM([]) -> (0,0)
    | IM([[]]) -> (0,0)
    | IM(x::rest) -> (length x,length rest + 1);;



(*A couple of extra functions I tried out \/ \/ \/*)
let rec seqadd : intseq -> intseq -> intseq =
  fun xs ys ->
  begin match xs, ys with
  | [], _ -> ys
  | _, [] -> xs
  | h::t, h2::t2 -> (h+h2)::(seqadd t t2)
  end;;

let rec rowadd: intseq list -> intseq list -> intseq list =
  fun row1 row2 ->
  match row1, row2 with
    | IM([[]]), IM([[_]]) -> row1
    | IM([[_]]), IM([[]]) -> row2
    | IM([[h::t]]), IM([[h2::t2]]) -> IM([[(h+h2)::(rowadd t t2)]]);;


(* matrix addition *)
let rec matrixadd: intmatrix -> intmatrix -> intmatrix =
  fun x y ->
(*TO DO*)

Ответы [ 2 ]

0 голосов
/ 30 октября 2019

Если вы уверены, что входные матрицы имеют одинаковый размер, вы можете использовать следующую функцию.
Она реализована для матрицы = int list list.

let add = 
  let rec add f a b = 
    match a, b with 
    | ah :: at, bh :: bt -> (f ah bh) :: (add f at bt)
    | [], []             -> []
  in
  add (add (+)) 
0 голосов
/ 24 октября 2019

Я бы разбил его на пару простых шагов, как вы начали делать - добавление одной строки и добавление нескольких строк, например.

let matrixadd m1 m2 =
  let rec addrow r1 r2 =
    match r1,r2 with
    | x :: x',  y :: y' -> x + y :: addrow x' y'
    | _                 -> []                     (* assume dims are correct *)
  in
  let rec addrows a b =
    match a,b with
    | r1 :: a', r2 :: b' -> addrow r1 r2 :: addrows a' b'
    | _                  -> []
  in
  let a, b = getbody m1, getbody m2 in
  IM (addrows a b)


(* example *)
let m1 = IM [[1;2]; [3;4]] in matrixadd m1 m1;;
(* - : intmatrix = IM [[2; 4]; [6; 8]] *)
...