Home > Software design >  Elementwise addition of lists in F#
Elementwise addition of lists in F#

Time:09-17

I'm trying to figure out how to do elementwise multiplication of two lists in F#. Example: [1;2;3] [1;2;3;4]=[2;4;6;4]. I'm quite a newbie and still struggle with the syntax of the code. My try is as follows:

let plus list_1 list_2 = function
    | list_1 list_2 -> [| for xi in list_1 yield
                          list_1[i] list_2[i]
                          |];;

It just give me an error, but can't figure out how to change it so it becomes right.

As a side note, if somebody know a beginner place to learn about lists in F#, a point in the right direction, is appreciated :)

CodePudding user response:

If you had two lists of the same size, then the easiest solution would be to use the List.map2 function. This takes two lists and it applies a specified function pairwise - so if you pass it ( ) as a function, it does exactly what you want:

let l1 = [1;2;3]
let l2 = [3;2;1]

List.map2 ( ) l1 l2

If your lists are of different size, then this is going to crash. I do not think there is any simple built-in solution, but you could define a function pad to pad a list with zeros and then make sure both lists are of the same size:

let pad n l = 
  List.append l 
    (List.init (n-List.length l) (fun _ -> 0))

let l1 = [1;2;3]
let l2 = [3;2;1;4]
let l = max (List.length l1) (List.length l2)

List.map2 ( ) (pad l l1) (pad l l2)

CodePudding user response:

In a similar vein to Tomas's answer, this makes both lists the "same" (infinite) length (using the lazy Seq instead of eager List), then trims the result to just the maximum length of the two lists:

let l1 = [1;2;3]
let l2 = [3;2;1;4]

let zeroes = Seq.initInfinite (fun _ -> 0)

let result =
    Seq.map2 ( ) (Seq.append l1 zeroes) (Seq.append l2 zeroes)
    |> Seq.take (max (List.length l1) (List.length l2))
    |> Seq.toList

CodePudding user response:

Here are two different solutions. Both combine the elements, that can be combined, and concatenate the result, onto the end.

It's up to you, to understand, how they work.

(* Avoiding SO syntax highlighting issues *)
let add x y = x   y
let mul x y = x * y


let dol f xs ys =
    let minElements = min (List.length xs) (List.length ys)
    List.append
        (List.map2 f (List.take minElements xs) (List.take minElements ys))        
        (List.skip minElements (if List.length xs = minElements then ys else xs))
 
dol add [1;2;3] [2;3;4;5;6] (* [3; 5; 7; 5; 6]  *)
dol mul [1;2;3] [2;3;4;5;6] (* [2; 6; 12; 5; 6] *)


let rec mol f xs ys =
    match xs,ys with
    | [],[]       -> []
    | [],ys       -> ys
    | xs,[]       -> xs
    | x::xs,y::ys -> (f x y) :: (mol f xs ys)

mol add [1;2;3] [2;3;4;5;6] (* [3; 5; 7; 5; 6]  *)
mol mul [1;2;3] [2;3;4;5;6] (* [2; 6; 12; 5; 6] *)
  • Related