Je n'ai plus écris d'OCAML depuis longtemps, je vais donc peut-être dire des bêtises.
Mais je me lance
> open Array
>
> let ( @@ ) f g x = f (g x)
>
> let produit mata matb =
> ....let coeff li col =
> ........fold_left ( + ) 0
> ............(init (length matb) (fun k -> mata.(li).(k) * matb.(k).(col)))
> ....in
> ....init (length mata) (init (try length matb.(0) with _ -> 0) @@ coeff)
On fait le produit des matrices mata et matb.
pour cela, on définit une fonction coeff li col qui donne le coefficient li,col de la matrice produit. Pour rappel, c'est mata(li,0)*matb(0,col)+...+mata(li,n)*mat(n,col)
Pour calculer ce coefficient, on utilise un fold_left qui prend en argument plein de trucs.
On voit entre autre apparaître (fun k->mata.(li).(k)*matb.(k).(col)). Si on appelle f cette fonction, le coefficient est donc f(0)+f(1)+f(2)+...+f(n).
Passons maintenant au fold_left. cette fonction prend en argument une fonction f, une valeur et une liste. Par exemple,
fold_left f 0 [1;2;3] = f (f (f (0 1) 2) 3
La fonction (+) est l'operateur + préfixé, c'est à dire (+) 1 2=1+2.
Pour additionner tous les éléments d'une liste, il suffit de faire un
fold_left (+) 0 l.
Si on recolle les morceaux, pour que la fonction coef retourne ce qu'il faut, il suffit que init n f tourne une la liste [f(0);f(1);...;f(n)]. Dans ce cas,
1. init (length matb) (fun k -> mata.(li).(k) * matb.(k).(col)) retourne la liste
[mata(li,0)*matb(0,col),...,mata(li,n)*mat(n,col)]
2. le fold_left (+) 0 ... rend la somme des éléments de la liste soit, le coefficient de li,col de la matrice.
Maintenant qu'on a une fonction coeff qui marche, il suffit d'utiliser init pour faire une jolie matrice. Si on part du principe qu'une matrice, c'est une famille de vecteurs, on construire un vecteur ligne, il suffit de faire un
init n k->coef li k.
On remarque que cette fonction a un paramètre (li). La fonction
li -> (init n k->coef li k) est donc la fonction qui rend le li-ème vecteur ligne de la matrice. En l'itérant à coup de init, on obtient une matrice.
Je passe l'utilisation du try with.
Bref, que d'explications pour un code de 6 lignes.
[^] # Re: Dommage...
Posté par fmaz fmaz . En réponse à la dépêche OCaml 3.10.0 est sorti. Évalué à 4.
Mais je me lance
> open Array
>
> let ( @@ ) f g x = f (g x)
>
> let produit mata matb =
> ....let coeff li col =
> ........fold_left ( + ) 0
> ............(init (length matb) (fun k -> mata.(li).(k) * matb.(k).(col)))
> ....in
> ....init (length mata) (init (try length matb.(0) with _ -> 0) @@ coeff)
On fait le produit des matrices mata et matb.
pour cela, on définit une fonction coeff li col qui donne le coefficient li,col de la matrice produit. Pour rappel, c'est mata(li,0)*matb(0,col)+...+mata(li,n)*mat(n,col)
Pour calculer ce coefficient, on utilise un fold_left qui prend en argument plein de trucs.
On voit entre autre apparaître (fun k->mata.(li).(k)*matb.(k).(col)). Si on appelle f cette fonction, le coefficient est donc f(0)+f(1)+f(2)+...+f(n).
Passons maintenant au fold_left. cette fonction prend en argument une fonction f, une valeur et une liste. Par exemple,
fold_left f 0 [1;2;3] = f (f (f (0 1) 2) 3
La fonction (+) est l'operateur + préfixé, c'est à dire (+) 1 2=1+2.
Pour additionner tous les éléments d'une liste, il suffit de faire un
fold_left (+) 0 l.
Si on recolle les morceaux, pour que la fonction coef retourne ce qu'il faut, il suffit que init n f tourne une la liste [f(0);f(1);...;f(n)]. Dans ce cas,
1. init (length matb) (fun k -> mata.(li).(k) * matb.(k).(col)) retourne la liste
[mata(li,0)*matb(0,col),...,mata(li,n)*mat(n,col)]
2. le fold_left (+) 0 ... rend la somme des éléments de la liste soit, le coefficient de li,col de la matrice.
Maintenant qu'on a une fonction coeff qui marche, il suffit d'utiliser init pour faire une jolie matrice. Si on part du principe qu'une matrice, c'est une famille de vecteurs, on construire un vecteur ligne, il suffit de faire un
init n k->coef li k.
On remarque que cette fonction a un paramètre (li). La fonction
li -> (init n k->coef li k) est donc la fonction qui rend le li-ème vecteur ligne de la matrice. En l'itérant à coup de init, on obtient une matrice.
Je passe l'utilisation du try with.
Bref, que d'explications pour un code de 6 lignes.