수학에서 집합을 표현하는 방법에는 열거형 표현법과 진술형 표현법으로 나뉘어진다.

{ 3, 7, 10, 14 } 는  열거형 표현이고,

{ y | y = n + 2n + [n/2] where n = 1, 2, 3, 4 } 는 진술형 표현이다. (단 여기서 [x] 는 가우스 기호)

(참고로 아래의 구문에서 기호 <- 는 집함의 원소 기호 ∈ 와 유사함을 염두에 두자.)

 

Haskell 언어에는 (집합의 진술형 표현과 유사한) Prelude 에서 기본적으로 제공되는 리스트 생성 구문이 있다.

명령 프롬프트> ghci
GHCi, version 7.4.2: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> [ x + 2*x + (div x 2) | x <- [1, 2, 3, 4] ]
[3,7,10,14]

 

OCaml 언어에는 저런 구문이 기본적으로 제공되지 않는다. 하지만 OCaml 언어로도 특별한 라이브러리를 쓰면 저렇게 편리하게 리스트를 생성할 수 있다. dynlink.cma 와 camlp4oof.cma 라이브러리를 쓰면 된다. cygwin 의 경우에는

     export OCAMLLIB=/lib/ocaml

을 미리해두어야 한다. (안 그러면  윈도우에 설치된 OCaml 의 라이브러리와 충돌이 난다.)

 

명령 프롬프트> ocaml dynlink.cma camlp4oof.cma
        Objective Caml version 3.12.1

        Camlp4 Parsing version 3.12.1

# [x + 2*x + x/2 | x <- [1; 2; 3; 4]];;
- : int list = [3; 7; 10; 14]

 

Haskell 언어로 3x3 Hilbert 행렬의 제곱을 계산해 보자.

명령 프롬프트> ghci
GHCi, version 7.4.2: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> import Data.Ratio
Prelude Data.Ratio> let a = [1, 2, 3]
Prelude Data.Ratio> let hilb3 = [ [ 1 % (i + j - 1) | i <- a ] | j <- a ]
Prelude Data.Ratio> hilb3
[[1 % 1,1 % 2,1 % 3],[1 % 2,1 % 3,1 % 4],[1 % 3,1 % 4,1 % 5]]
Prelude Data.Ratio> import Data.List
Prelude Data.Ratio Data.List> transpose hilb3
[[1 % 1,1 % 2,1 % 3],[1 % 2,1 % 3,1 % 4],[1 % 3,1 % 4,1 % 5]]
Prelude Data.Ratio Data.List> let mmult a b = [ [ sum $ zipWith (*) ar bc | bc <
- (transpose b) ] | ar <- a ]
Prelude Data.Ratio Data.List> mmult hilb3 hilb3
[[49 % 36,3 % 4,21 % 40],[3 % 4,61 % 144,3 % 10],[21 % 40,3 % 10,769 % 3600]]
Prelude Data.Ratio Data.List>

 

이제는 OCaml 언어로 3x3 Hilbert 행렬의 제곱을 계산해 보자.

명령 프롬프트> ocaml dynlink.cma camlp4oof.cma
        Objective Caml version 3.12.1

        Camlp4 Parsing version 3.12.1

let rec transpose list = match list with
    | []             -> []
    | []   :: xss    -> transpose xss
    | (x::xs) :: xss ->
        (x :: List.map List.hd xss) :: transpose (xs :: List.map List.tl xss) ;;
val transpose : 'a list list -> 'a list list = <fun>
# transpose [ [2; 3]; [1; 5] ] ;;
- : int list list = [[2; 1]; [3; 5]]
# let sum list = List.fold_left (+) 0 list ;;
val sum : int list -> int = <fun>
# sum [1; 2; 3] ;;
- : int = 6
# #load "nums.cma" ;;
# 2/3 ;;
- : int = 0
# open Num ;;
# num_of_string "2/3" ;;
- : Num.num = Ratio <abstr>
# let sum list = List.fold_left ( +/ ) (num_of_int 0) list ;;
val sum : Num.num list -> Num.num = <fun>
let v = List.map num_of_string [ "1/2"; "1/3" ] ;;
val v : Num.num list = [Ratio <abstr>; Ratio <abstr>]
# sum v ;;
- : Num.num = Ratio <abstr>
# string_of_num (sum v) ;;
- : string = "5/6"
let rec zipWith f l1 l2 =
         match (l1, l2) with
           ([], _) -> []
         | (_, []) -> []
         | (x1 :: rl1, x2 :: rl2) -> (f x1 x2) :: (zipWith f rl1 rl2) ;;
val zipWith : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list = <fun>
# let mmult a b = [ [ sum (zipWith ( */ ) ar bc) | bc <- (transpose b) ] | ar <- a ]  ;;
val mmult : Num.num list list -> Num.num list list -> Num.num list list =
  <fun>
# let a = [1; 2; 3] ;;
val a : int list = [1; 2; 3]
# let hilb3 = [ [ (num_of_int 1) // (num_of_int  (i +  j - 1)) | i <- a ] | j <- a ] ;;
val hilb3 : Num.num list list =
  [[Int 1; Ratio <abstr>; Ratio <abstr>];
   [Ratio <abstr>; Ratio <abstr>; Ratio <abstr>];
   [Ratio <abstr>; Ratio <abstr>; Ratio <abstr>]]
# string_of_num (List.nth (List.nth hilb3 2) 2) ;;
- : string = "1/5"
# let matB = mmult hilb3 hilb3 ;;
val matB : Num.num list list =
  [[Ratio <abstr>; Ratio <abstr>; Ratio <abstr>];
   [Ratio <abstr>; Ratio <abstr>; Ratio <abstr>];
   [Ratio <abstr>; Ratio <abstr>; Ratio <abstr>]]
# open Printf ;;
# let print_vector v = List.iter (fun x -> printf "%s, " (string_of_num x)) v ;;
val print_vector : Num.num list -> unit = <fun>
# print_vector (List.nth hilb3 2) ;;
1/3, 1/4, 1/5, - : unit = ()
# let print_matrix m = List.iter (fun x -> print_vector x; print_newline()) m ;;
val print_matrix : Num.num list list -> unit = <fun>
# print_matrix hilb3 ;;
1, 1/2, 1/3,
1/2, 1/3, 1/4,
1/3, 1/4, 1/5,
- : unit = ()
# print_matrix matB ;;
49/36, 3/4, 21/40,
3/4, 61/144, 3/10,
21/40, 3/10, 769/3600,
- : unit = ()
# #quit ;;

 

F# 언어로는 부동소수점수로 3x3 Hilber 행렬의 제곱을 계산해 보았다.

명령프롬프트> fsi

Microsoft (R) F# 2.0 Interactive 빌드 4.0.40219.1
Copyright (c) Microsoft Corporation. 모든 권리 보유.

도움말을 보려면 #help;;를 입력하십시오.

> let array3 = [| for i in 1 .. 10 -> i * i |] ;;

val array3 : int [] = [|1; 4; 9; 16; 25; 36; 49; 64; 81; 100|]

> let a = [ 1..3 ] ;;

val a : int list = [1; 2; 3]

> let hilb3 = [ for i in a -> [ for j in a -> 1.0/(float (i + j - 1)) ] ] ;;

val hilb3 : float list list =
  [[1.0; 0.5; 0.3333333333]; [0.5; 0.3333333333; 0.25];
   [0.3333333333; 0.25; 0.2]]

> let sum list = List.fold ( + ) (0.0) list ;;

val sum : float list -> float

> sum [5.0; 2.1] ;;
val it : float = 7.1
> let rec zipWith f l1 l2 =
      match (l1, l2) with
         ([], _) -> []
       | (_, []) -> []
      | (x1 :: rl1, x2 :: rl2) -> (f x1 x2) :: (zipWith f rl1 rl2) ;;

val zipWith : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list

> let mmult a b = [ for ar in a -> [ for bc in b -> sum (zipWith ( * ) ar bc) ] ] ;;

val mmult : seq<float list> -> seq<float list> -> float list list

> let matB = mmult hilb3 hilb3 ;;

val matB : float list list =
  [[1.361111111; 0.75; 0.525]; [0.75; 0.4236111111; 0.3];
   [0.525; 0.3; 0.2136111111]]

> #quit ;;

 

 

또 다음은 F# 의 PowerPack.dll 라이브리의 BigRational 을 이영하여 3x3 Hilbert 행렬의 제곱을 계산하는 과정이다.

명령 프롬프트> fsi

Microsoft (R) F# 2.0 Interactive 빌드 4.0.40219.1
Copyright (c) Microsoft Corporation. 모든 권리 보유.

도움말을 보려면 #help;;를 입력하십시오.

> #r "FSharp.PowerPack.dll" ;;

--> 'C:\test\f#\FSharp.PowerPack.dll'이(가) 참조되었습니다.

> let r = (1N/2N) * (1N/3N) ;; // 1/6
세션을 'C:\test\f#\FSharp.PowerPack.dll'에 바인딩하는 중...

val r : BigRational = 1/6N

> let sum list = List.fold ( + ) (0N) list ;;

val sum : BigRational list -> BigRational

> sum [5N; 2N/3N] ;;
val it : BigRational = 17/3N
> bigint 2;;
val it : System.Numerics.BigInteger = 2 {IsEven = true;
                                         IsOne = false;
                                         IsPowerOfTwo = true;
                                         IsZero = false;
                                         Sign = 1;}
> open System ;;
> open System.Numerics ;;
> BigRational.FromInt 5 ;;
val it : BigRational = 5N
> let a = [ 1..3 ] ;;

val a : int list = [1; 2; 3]

> let hilb3 = [ for i in a -> [ for j in a -> 1N/(BigRational.FromInt (i + j - 1
- )) ] ] ;;

val hilb3 : BigRational list list =
  [[1N; 1/2N; 1/3N]; [1/2N; 1/3N; 1/4N]; [1/3N; 1/4N; 1/5N]]

> let rec zipWith f l1 l2 =
       match (l1, l2) with
         ([], _) -> []
       | (_, []) -> []
       | (x1 :: rl1, x2 :: rl2) -> (f x1 x2) :: (zipWith f rl1 rl2) ;;

val zipWith : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list

let mmult a b = [ for ar in a -> [ for bc in b -> sum (zipWith ( * ) ar bc) ]
- ] ;;

val mmult :
  seq<BigRational list> -> seq<BigRational list> -> BigRational list list

let matB = mmult hilb3 hilb3 ;;

val matB : BigRational list list =
  [[49/36N; 3/4N; 21/40N]; [3/4N; 61/144N; 3/10N]; [21/40N; 3/10N; 769/3600N]]

> #quit ;;


 

Posted by Scripter
,