Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding two arrays of float values in Haskell

Tags:

haskell

Can anyone provide an example showing the addition of two arrays in Haskell please?

I'm fairly new to Haskell, and I generally find that I can learn quicker by taking something simple that I understand in one language and seeing how another programmer might do it in their language.

It would be great to see some code that creates two arrays of floats and calls a function which results in an array with the summed values. Something equivalent to the following C code.

void addTwoArrays(float *a, float *b, float *c, int len) {
    int idx=0;
    while (idx < len) {
        c[idx] = a[idx] + b[idx];
    }
}

int N = 4;
float *a = (float*)malloc(N * sizeof(float));
float *b = (float*)malloc(N * sizeof(float));
float *c = (float*)malloc(N * sizeof(float));

a[0]=0.0; a[1]=0.1; a[2]=0.2; a[3]=0.4;
b[0]=0.0; b[1]=0.1; b[2]=0.2; b[3]=0.4;
addTwoArrays(a,b,c,N);

Seeing Haskell code that achieved the same result would help my understanding a lot. I guess the haskell version would create the result array and return it, like c = addTwoArrays(a,b,N)?

Thanks.

like image 241
Alp Avatar asked Sep 10 '11 11:09

Alp


3 Answers

For simplicity's sake I'm going to use (linked) lists instead of arrays, as they can be more easily created using list literals.

a = [0, 0.1, 0.2, 0.4]
b = [0, 0.1, 0.2, 0.4]
c = zipWith (+) a b

zipWith is a function which takes another function and two lists and then creates a new list by applying the given function to each pair of elements of the lists at the same index. So here the function we give to zipWith is + and thus it adds the elements of the two lists.

If we wanted to do this without using zipWith we could define addTwoLists like this:

addTwoLists [] _ = []
addTwoLists _ [] = []
addTwoLists (x:xs) (y:ys) = (x+y) : (addTwoLists xs ys)

The logic here is that when one of the lists is empty, addTwoLists will return an empty list. Otherwise it will return the sum of the heads of the two lists (i.e. a+b) prepended to the result of adding together their tails.

like image 149
sepp2k Avatar answered Nov 19 '22 09:11

sepp2k


In haskell, for this question, you will use lists instead of arrays (however array, vector exist in Haskell, thanks Thomas M. DuBuisson for his comment) and code will be like this

addTwoArrays :: (Num a) => [a]->[a]->[a]
addTwoArrays _ [] = []
addTwoArrays [] _ = []
addTwoArrays (x:xs) (y:ys) = (x+y) : (addTwoArrays xs ys)

This function will take two arrays that has numeric values (ints, floats, etc) and sum them until the shorter ones length.

However we can write same function with using functional language features:

addTwoArrays :: (Num a) => [a]->[a]->[a]
addTwoArrays xs ys :: zipWith (+) xs ys

Both functions will take two lists and returns the sum, based on the shorter one.

addTwoArrays [1.0, 2.0, 3.0] [2.0, 3.0, 4.0] --returns [3.0, 5.0, 7.0] and

addTwoArrays [1.0, 2.0, 3.0] [2.0, 3.0] --returns [3.0, 5.0]
like image 39
reader_1000 Avatar answered Nov 19 '22 08:11

reader_1000


In addition to the other answers: The zipping functions also exists for Vectors. Vectors are real arrays and not linked lists, though the computer may optimize the vectors away if possible. Look at the link above to get further information.

like image 4
fuz Avatar answered Nov 19 '22 08:11

fuz