Python용 소스파일 testForFor.py를 F# 용으로 수정한 것이다.
F#의 if 구문과 for 구문이 Python의 것과 (들여쓰기하는 것 까지) 많이 닮았다.
F#은 함수형 언어기도 하고 명령형 언어이기도 하므로, 여기서는 가급적 F#의 명령형 언어의 특징을 위주로 작성하였다.

  1. (* 
  2.  *  Filename: TestForFor.fs
  3.  *
  4.  *  Compile:  fsc TestForFor.fs
  5.  *  Execute:  TestForFor
  6.  *
  7.  *  Date:  2010. 7. 13
  8.  *)
  9. # light
  10. let getDan dan =
  11.     let t = [| for i in 1..19 -> "" |]
  12.     for j in 0..(19 - 1) do
  13.         let mutable sa = sprintf "%d" dan
  14.         if (String.length sa) < 2 then
  15.             sa <- sprintf " %d" dan
  16.         let mutable sb = sprintf "%d" (j + 1)
  17.         if (String.length sb) < 2 then
  18.             sb <- sprintf " %d" (j + 1)
  19.         let mutable sval = sprintf "%d" (dan*(j + 1))
  20.         if (String.length sval) < 2 then
  21.             sval <- sprintf "  %d" (dan*(j + 1))
  22.         elif (String.length sval) < 3 then
  23.             sval <- sprintf " %d" (dan*(j + 1))
  24.         t.[j] <- sa + " x " + sb + " = " + sval
  25.     t
  26. // 19단표를 모두 80컬럼 컨솔에 출력한다.
  27. let printAllNineteenDan =
  28.     let arr = [| for u in 1..19 -> [| for j in 1..18 -> "" |] |]
  29.     for i in 2..(20 - 1) do
  30.         arr.[i - 2] <- (getDan i )
  31.     // F# 소스 코드에서는 리스트 대신 배열을 사용한다.
  32.     let d = [| 2; 7; 11; 16 |]      // 각 줄단위 블럭의 첫단
  33.     let counter = [| 5; 4; 5; 4 |]  // 각 줄단위 블럭에 속한 단의 개수
  34.     let lines = [| for u in 1..19 -> "" |]
  35.     for k in 0..((Array.length d) - 1) do
  36.         // 8-바이트 길이의 한 줄씩 완성
  37.         for i in 0..(19 - 1) do
  38.             lines.[i] <- (arr.[d.[k]-2].[i])
  39.             for j in 1..(counter.[k] - 1) do
  40.                 lines.[i] <- ((lines.[i]) + "   " +  (arr.[d.[k]-2+j].[i]))
  41.         // 80 바이트 길이의 한 줄씩 출력
  42.         for i in 0..(19 - 1) do
  43.             printfn "%s" (lines.[i])
  44.         printfn ""
  45. printAllNineteenDan



컴파일: 
Prompt> fsc TestForFor.fㄴ 

실행: 
Prompt> TestForFor 
2 x  1 =   2    3 x  1 =   3    4 x  1 =   4    5 x  1 =   5    6 x  1 =   6
2 x  2 =   4    3 x  2 =   6    4 x  2 =   8    5 x  2 =  10    6 x  2 =  12
2 x  3 =   6    3 x  3 =   9    4 x  3 =  12    5 x  3 =  15    6 x  3 =  18
2 x  4 =   8    3 x  4 =  12    4 x  4 =  16    5 x  4 =  20    6 x  4 =  24
2 x  5 =  10    3 x  5 =  15    4 x  5 =  20    5 x  5 =  25    6 x  5 =  30
2 x  6 =  12    3 x  6 =  18    4 x  6 =  24    5 x  6 =  30    6 x  6 =  36
2 x  7 =  14    3 x  7 =  21    4 x  7 =  28    5 x  7 =  35    6 x  7 =  42
2 x  8 =  16    3 x  8 =  24    4 x  8 =  32    5 x  8 =  40    6 x  8 =  48
2 x  9 =  18    3 x  9 =  27    4 x  9 =  36    5 x  9 =  45    6 x  9 =  54
2 x 10 =  20    3 x 10 =  30    4 x 10 =  40    5 x 10 =  50    6 x 10 =  60
2 x 11 =  22    3 x 11 =  33    4 x 11 =  44    5 x 11 =  55    6 x 11 =  66
2 x 12 =  24    3 x 12 =  36    4 x 12 =  48    5 x 12 =  60    6 x 12 =  72
2 x 13 =  26    3 x 13 =  39    4 x 13 =  52    5 x 13 =  65    6 x 13 =  78
2 x 14 =  28    3 x 14 =  42    4 x 14 =  56    5 x 14 =  70    6 x 14 =  84
2 x 15 =  30    3 x 15 =  45    4 x 15 =  60    5 x 15 =  75    6 x 15 =  90
2 x 16 =  32    3 x 16 =  48    4 x 16 =  64    5 x 16 =  80    6 x 16 =  96
2 x 17 =  34    3 x 17 =  51    4 x 17 =  68    5 x 17 =  85    6 x 17 = 102
2 x 18 =  36    3 x 18 =  54    4 x 18 =  72    5 x 18 =  90    6 x 18 = 108
2 x 19 =  38    3 x 19 =  57    4 x 19 =  76    5 x 19 =  95    6 x 19 = 114

7 x  1 =   7    8 x  1 =   8    9 x  1 =   9   10 x  1 =  10
7 x  2 =  14    8 x  2 =  16    9 x  2 =  18   10 x  2 =  20
7 x  3 =  21    8 x  3 =  24    9 x  3 =  27   10 x  3 =  30
7 x  4 =  28    8 x  4 =  32    9 x  4 =  36   10 x  4 =  40
7 x  5 =  35    8 x  5 =  40    9 x  5 =  45   10 x  5 =  50
7 x  6 =  42    8 x  6 =  48    9 x  6 =  54   10 x  6 =  60
7 x  7 =  49    8 x  7 =  56    9 x  7 =  63   10 x  7 =  70
7 x  8 =  56    8 x  8 =  64    9 x  8 =  72   10 x  8 =  80
7 x  9 =  63    8 x  9 =  72    9 x  9 =  81   10 x  9 =  90
7 x 10 =  70    8 x 10 =  80    9 x 10 =  90   10 x 10 = 100
7 x 11 =  77    8 x 11 =  88    9 x 11 =  99   10 x 11 = 110
7 x 12 =  84    8 x 12 =  96    9 x 12 = 108   10 x 12 = 120
7 x 13 =  91    8 x 13 = 104    9 x 13 = 117   10 x 13 = 130
7 x 14 =  98    8 x 14 = 112    9 x 14 = 126   10 x 14 = 140
7 x 15 = 105    8 x 15 = 120    9 x 15 = 135   10 x 15 = 150
7 x 16 = 112    8 x 16 = 128    9 x 16 = 144   10 x 16 = 160
7 x 17 = 119    8 x 17 = 136    9 x 17 = 153   10 x 17 = 170
7 x 18 = 126    8 x 18 = 144    9 x 18 = 162   10 x 18 = 180
7 x 19 = 133    8 x 19 = 152    9 x 19 = 171   10 x 19 = 190

11 x  1 =  11   12 x  1 =  12   13 x  1 =  13   14 x  1 =  14   15 x  1 =  15
11 x  2 =  22   12 x  2 =  24   13 x  2 =  26   14 x  2 =  28   15 x  2 =  30
11 x  3 =  33   12 x  3 =  36   13 x  3 =  39   14 x  3 =  42   15 x  3 =  45
11 x  4 =  44   12 x  4 =  48   13 x  4 =  52   14 x  4 =  56   15 x  4 =  60
11 x  5 =  55   12 x  5 =  60   13 x  5 =  65   14 x  5 =  70   15 x  5 =  75
11 x  6 =  66   12 x  6 =  72   13 x  6 =  78   14 x  6 =  84   15 x  6 =  90
11 x  7 =  77   12 x  7 =  84   13 x  7 =  91   14 x  7 =  98   15 x  7 = 105
11 x  8 =  88   12 x  8 =  96   13 x  8 = 104   14 x  8 = 112   15 x  8 = 120
11 x  9 =  99   12 x  9 = 108   13 x  9 = 117   14 x  9 = 126   15 x  9 = 135
11 x 10 = 110   12 x 10 = 120   13 x 10 = 130   14 x 10 = 140   15 x 10 = 150
11 x 11 = 121   12 x 11 = 132   13 x 11 = 143   14 x 11 = 154   15 x 11 = 165
11 x 12 = 132   12 x 12 = 144   13 x 12 = 156   14 x 12 = 168   15 x 12 = 180
11 x 13 = 143   12 x 13 = 156   13 x 13 = 169   14 x 13 = 182   15 x 13 = 195
11 x 14 = 154   12 x 14 = 168   13 x 14 = 182   14 x 14 = 196   15 x 14 = 210
11 x 15 = 165   12 x 15 = 180   13 x 15 = 195   14 x 15 = 210   15 x 15 = 225
11 x 16 = 176   12 x 16 = 192   13 x 16 = 208   14 x 16 = 224   15 x 16 = 240
11 x 17 = 187   12 x 17 = 204   13 x 17 = 221   14 x 17 = 238   15 x 17 = 255
11 x 18 = 198   12 x 18 = 216   13 x 18 = 234   14 x 18 = 252   15 x 18 = 270
11 x 19 = 209   12 x 19 = 228   13 x 19 = 247   14 x 19 = 266   15 x 19 = 285

16 x  1 =  16   17 x  1 =  17   18 x  1 =  18   19 x  1 =  19
16 x  2 =  32   17 x  2 =  34   18 x  2 =  36   19 x  2 =  38
16 x  3 =  48   17 x  3 =  51   18 x  3 =  54   19 x  3 =  57
16 x  4 =  64   17 x  4 =  68   18 x  4 =  72   19 x  4 =  76
16 x  5 =  80   17 x  5 =  85   18 x  5 =  90   19 x  5 =  95
16 x  6 =  96   17 x  6 = 102   18 x  6 = 108   19 x  6 = 114
16 x  7 = 112   17 x  7 = 119   18 x  7 = 126   19 x  7 = 133
16 x  8 = 128   17 x  8 = 136   18 x  8 = 144   19 x  8 = 152
16 x  9 = 144   17 x  9 = 153   18 x  9 = 162   19 x  9 = 171
16 x 10 = 160   17 x 10 = 170   18 x 10 = 180   19 x 10 = 190
16 x 11 = 176   17 x 11 = 187   18 x 11 = 198   19 x 11 = 209
16 x 12 = 192   17 x 12 = 204   18 x 12 = 216   19 x 12 = 228
16 x 13 = 208   17 x 13 = 221   18 x 13 = 234   19 x 13 = 247
16 x 14 = 224   17 x 14 = 238   18 x 14 = 252   19 x 14 = 266
16 x 15 = 240   17 x 15 = 255   18 x 15 = 270   19 x 15 = 285
16 x 16 = 256   17 x 16 = 272   18 x 16 = 288   19 x 16 = 304
16 x 17 = 272   17 x 17 = 289   18 x 17 = 306   19 x 17 = 323
16 x 18 = 288   17 x 18 = 306   18 x 18 = 324   19 x 18 = 342
16 x 19 = 304   17 x 19 = 323   18 x 19 = 342   19 x 19 = 361



 

Posted by Scripter
,


소스 파일명: TestNoWhile.fs

  1. (*
  2.  *  Filename: TestNoWhile.fs
  3.  *
  4.  *  Purpose:  Example using the while loop syntax
  5.  *                while ....
  6.  *
  7.  *  Compile: fsc --codepage:949 TestNoWhile.fs
  8.  *  Execute: TestNoWhile -200 300
  9.  *)
  10. #light
  11. // 사용법 표시
  12. let printUsage x =
  13.     printfn "Using: TestNoWhile [integer1] [integer2]"
  14.     printfn "This finds the greatest common divisor of the given two integers."
  15. let cmdArgs = System.Environment.GetCommandLineArgs()
  16. if not ((Array.length cmdArgs) = 3) then
  17.     printUsage 0
  18.     exit(1)
  19. // --------------------------------------
  20. // 명령행 인자의 두 스트링을 가져와서
  21. // 정수 타입으로 변환하여
  22. // 변수 val1과 val2에 저장한다.
  23. let val1 = int cmdArgs.[1]
  24. let val2 = int cmdArgs.[2]
  25. // a는 |val1|, |val2| 중 큰 값
  26. let mutable a = abs val1
  27. let mutable b = abs val2
  28. let max x y = if y > x then y else x
  29. let min x y = if y > x then x else y
  30. let maxab = max a b
  31. let minab = min a b
  32. a <- maxab
  33. b <- minab
  34. // --------------------------------------
  35. // 재귀호출 Euclidean 알고리즘
  36. //
  37. //     Euclidean 알고리즘의 반복 (나머지가 0이 될 때 까지)
  38. //     나머지가 0이면 그 때 나눈 수(제수) x가 최대공약수(GCD)이다.
  39. let rec gcdRecursive x y =
  40.     match y with
  41.     | 0 -> x
  42.     | _ -> gcdRecursive y (x % y)
  43. let gcd = gcdRecursive a b
  44. // 최대공약수(GCD)를 출력한다.
  45. printfn "GCD(%d, %d) = %d" val1 val2 gcd



컴파일:

Command> fsc TestNoWhile.fs

실행:

Command> TestNoWhile
Using: TestNoWhile [integer1] [integer2]
This finds the greatest common divisor of the given two integers.

Command> TestNoWhile -200 300
GCD(-200, 300) = 100

Command> TestNoWhile -200 0
GCD(-200, 0) = 200

Command> TestNoWhile 125 100
GCD(125, 100) = 25

Command> TestNoWhile 23 25
GCD(23, 25) = 1



Posted by Scripter
,


소스 파일명: TestWhile.fs

  1. (*
  2.  *  Filename: TestWhile.fs
  3.  *
  4.  *  Purpose:  Example using the while loop syntax
  5.  *                while ....
  6.  * 
  7.  *  Compile: fsc --codepage:949 TestWhile.fs
  8.  *  Execute: TestWhile -200 300
  9.  *)
  10. #light
  11. // 사용법 표시
  12. let printUsage x =
  13.     printfn "Using: TestWhile.py [integer1] [integer2]"
  14.     printfn "This finds the greatest common divisor of the given two integers."
  15. let cmdArgs = System.Environment.GetCommandLineArgs()
  16. if not ((Array.length cmdArgs) = 3) then
  17.     printUsage 0
  18.     exit(1)
  19. // --------------------------------------
  20. // 명령행 인자의 두 스트링을 가져와서
  21. // 정수 타입으로 변환하여
  22. // 변수 val1과 val2에 저장한다.
  23. let val1 = int cmdArgs.[1]
  24. let val2 = int cmdArgs.[2]
  25. // a는 |val1|, |val2| 중 큰 값
  26. let mutable a = abs val1
  27. let mutable b = abs val2
  28. if a < b then
  29.     a <- abs val2
  30.     b <- abs val1
  31. if b = 0 then
  32.     printfn "GCD(%d, %d) = %d" val1 val2 a
  33.     exit(0)
  34. // --------------------------------------
  35. // Euclidean 알고리즘의 시작
  36. //
  37. // a를 b로 나누어 몫은 q에, 나머지는 r에 저장
  38. let mutable q = a / b
  39. let mutable r = a % b
  40. // --------------------------------------
  41. // Euclidean 알고리즘의 반복 (나머지 r이 0이 될 때 까지)
  42. while not (r = 0) do
  43.     a <- b
  44.     b <- r
  45.     q <- a / b
  46.     r <- a % b
  47. // 나머지가 0이면 그 때 나눈 수(제수) b가 최대공약수(GCD)이다.
  48. let gcd = b
  49. // 최대공약수(GCD)를 출력한다.
  50. printfn "GCD(%d, %d) = %d" val1 val2 gcd



컴파일:

Command> fsc TestWhile.fs

실행:

Command> TestWhile
Using: TestWhile [integer1] [integer2]
This finds the greatest common divisor of the given two integers.

Command> TestWhile -200 300
GCD(-200, 300) = 100

Command> TestWhile -200 0
GCD(-200, 0) = 200

Command> TestWhile 125 100
GCD(125, 100) = 25

Command> TestWhile 23 25
GCD(23, 25) = 1



Posted by Scripter
,

F# 언어는 함수형 언어이면서도 명령형 언어의 특징을 대부분 가지고 잇다.
따라서 보통의 for 구문을 쓸 수도 있고, 재귀호출 함수릉 만들어 쓸 수도 있다.

아래의 소스에서 함수 printDan 은 보통의 for 구문을 쓴 것이고
함수 printAnotherDan 은 재귀호출 함수를 쓴 것이다.


소스 파일명: forTest.fs
------------------------------[소스 시작]
let printDan dan =
    for i in 1..9 do
        printfn "%d x %d = %d" dan i (dan*i)

let printAnotherDan (dan : int) =
    let rec loop l =
        match l with
        | x :: xs -> printfn "%d x %d = %d" dan x (dan*x); loop xs
        | [] -> None
    loop [1..9]

printDan 2
printAnotherDan 3 |> ignore
------------------------------[소스 끝]


컴파일> fsc forTest.fs

실행> forTest2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27




Posted by Scripter
,

Python 언어에서 명령행 인자는 sys.argv 라는 변수로 처리한다.
sys.argv는 모듈 sys에 속하는 변수 argv를 의미하며, 이는 명령행 실행시 옵션으로 입력된 인자들을 스트링 값으로 모아둔 리스트형의 변수이다.
모듈 sys을 하기 위해서는

        import sys

라는 수입(import) 구문을 소스 선두 부분에 적어주어야 한다.

C/C++/Java/Ruby 언어들과는 달리 리스트의 0번의 값(즉 sys.argv[0])은 python 명령 바로 다음에 입력된 (실행될) Python 소스파일명을 가리키므로, 1번부터 처리해야 한다. 즉 Python 언어에서 sys.argv[1], sys.argv[2], sys.argv[3], ... 들이 각각 C 언어의 argv[0], argv[1], argv[2], .... 들에 해당하며, Java 언어의 args[0], args[1], args[2], ... 들에 해당한다.

다음 소스의 앞 부분에

    #! /usr/bin/python
    # -*- encoding: euc-kr -*-

를 적어둔 것은 소스 코드에서 (주석문에) ASCII 가 아닌 문자(여기서는 한글 euc-kr)를 소스 코드에서 사용하고 있기 때문이다. 이 두 줄은

    #! /usr/bin/python
    # coding: euc-kr

으로 하여도 된다. 만일 소스 코드 파일을 utf-8 인코딩으로 저장하였다면 euc-kr 대신 utf-8로 하여야 할 것이다. (참고로, Ubuntu 플랫폼에서는 소스파일 저장시 반드시 utf-8 인코딩으로 저장하여야 한다.)


소스파일명: testArguments.fs

  1. // Filename: testArguments.fs
  2. let main =
  3.     let cmdArgs = System.Environment.GetCommandLineArgs()
  4.     let args = cmdArgs.[1..]
  5.     let arr : float list = [ for i in args -> double i]
  6.     printfn "Count of arguments: %O" (List.length arr)
  7.     printfn "The sum of arguments is %O" (List.sum arr)


컴파일> fsc testArguments.fs

실행> testArguments 1 2 3 4
Count of arguments: 4
The sum of arguments is 10




 

Posted by Scripter
,
컨솔에 문자 출력하는 F# 구문은

       print "문자열(스트링)"



       printfn "문자열(스트링)"

이다. 여기서 printfnd는 출력 후 개행한다는 것만 다르나.
 

소스 파일명: hello.fs
------------------------------[소스 시작]
printfn "Hello, world!"
------------------------------[소스 끝]

(한글이 있는 소스는 옵션 --codepage:949 를 사용하여 컴파일한다.)
컴파일> fsc hello.fs
실행> hello
Hello, world!


Posted by Scripter
,


소스 파일명: TestIf.fs

  1. // Filename: TestIf.fs
  2. #light
  3. let printUsing x =
  4.      printfn "Using: TestIf [number]"
  5.      printfn "This determines whether the number is positive or not."
  6. let (|Float|_|) (str: string) =
  7.    let mutable floatvalue = 0.0
  8.    if System.Double.TryParse(str, &floatvalue) then Some(floatvalue)
  9.    else None
  10. let isPositveNegative = function
  11.      | x when x > 0.0 -> "positive"
  12.      | x when x < 0.0 -> "negative"
  13.      | x when x = 0.0 -> "zero"
  14.      | _ -> "not a floating number"
  15. let doCheck s =
  16.     match s with
  17.     | Float s ->
  18.         let mutable y = 1.0
  19.         y <- System.Convert.ToDouble(s)
  20.         printfn "%g is %O." y (isPositveNegative y)
  21.     | _ -> printUsing 0
  22. let cmdArgs = System.Environment.GetCommandLineArgs()
  23. if (Array.length cmdArgs > 1) then
  24.     doCheck (cmdArgs.[1])
  25. else printUsing 0



컴파일> fsc TestIf.fs

실행> TestIf -1.2
-1.2 is negative.


실행> TestIf 0.0
-1.2 is zero.




Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.


Posted by Scripter
,

필요한데가 많을 것 같아서 올려 놓는다.

//  See  http://msdn.microsoft.com/en-us/library/dd233248.aspx

let (|Integer|_|) (str: string) =
   let mutable intvalue = 0
   if System.Int32.TryParse(str, &intvalue) then Some(intvalue)
   else None

let (|Float|_|) (str: string) =
   let mutable floatvalue = 0.0
   if System.Double.TryParse(str, &floatvalue) then Some(floatvalue)
   else None

let parseNumeric str =
   match str with
     | Integer i -> printfn "%d : Integer" i
     | Float f -> printfn "%f : Floating point" f
     | _ -> printfn "%s : Not matched." str

parseNumeric "1.1"
parseNumeric "0"
parseNumeric "0.0"
parseNumeric "10"
parseNumeric "Something else"




실행 결과:

1.100000 : Floating point
0 : Integer
0.000000 : Floating point
10 : Integer
Something else : Not matched.


Posted by Scripter
,

F# 프로그래밍 중에 한글 출력을 시도하였다.
그러나 당연히 되리라고 믿었던 printfn 에 의한 한글 출력이 되지 않았다.

printfn "한글"

이 한 줄 짜리 F# 소스를 컴파일하고 실행하면

???

가 출력된다. 소스를 UTF8 인코딩으로 저장해 보기도 하고, 명령창을 chcp 65001 하여 UTF8 창으로 바꾸어 보기도 하였지만 허사였다.
인터넷 검색을 해보아도 해결책을 찾지 못했다.
아마도 F# 언어를 사용하는 사람들은 적어도 한글을 안써도 되는 듯...
(.NET에서 한글을 못 쓰면 문제가 많을텐데...)

그러나 알고 보면 쉬운 것.
fsc 로 컴파일할 때  --codepage:숫자 옵션으로 인코딩 숫자(예를 들어 949)를 지정하면 된다.

우선 F# 소스를 하나 보자

// 파일명: hello.fs

(* 한글이 있는
   여러 줄
   주석문 *)
printfn "Hello"
printfn "안녕하세요?"

// 한글이 있는 주석문
let a = sprintf "%s을 %s당..." "한글 출력" "연습합니"
printfn "F# 프로그래밍에서 %s" a



컴파일하기:
D:\test\f#>fsc --codepage:949 hello.fs
Microsoft (R) F# 2.0 Compiler build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

실행하기:
D:\test\f#>hello
Hello
안녕하세요?
F# 프로그래밍에서 한글 출력을 연습합니당...


* 참고: fsi 에서는 한글 입력과 출력이 잘 되지 않는다.


* Visual Studio 통합 환경에서는 한글 문제가 발생하지 않는다.






Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

Posted by Scripter
,

목적:
http://stackoverflow.com/questions/1907709/a-simple-wrapper-for-f-to-do-matrix-operations 에 올려진 소스에서 String.spit 관련를 문제 해결하자.

테스트를 위해 필요한 자료:   dnAnalytics
                                        F# Power Pack


// 파일명: TestFSharpMatrix.fs (원래 소스)

#r @"D:\WORK\tools\dnAnalytics_windows_x86\bin\dnAnalytics.dll" 
#r @"FSharp.PowerPack.dll"
 
 
open dnAnalytics
.LinearAlgebra
 
open
Microsoft.FSharp.Math
 
open dnAnalytics
.LinearAlgebra.Decomposition
 
 
// F# matrix -> ndAnalytics DenseMatrix
 
let mat2dnmat
(mat:matrix) =
 
    let m
= new DenseMatrix(mat.ToArray2D())
 
    m 
 
// ndAnalytics DenseMatrix -> F# matrix
 
let dnmat2mat
(dnmat:DenseMatrix) =
 
    let n
= dnmat.Rows
 
    let m
= dnmat.Columns
 
    let mat
= Matrix.create n m 0.
 
   
for i=0 to n-1 do
 
       
for j=0 to m-1 do
 
            mat
.[i,j] <- dnmat.Item(i,j)
 
    mat 
 
// random matrix
 
let randmat n m
=
 
    let r
= new System.Random()
 
    let ranlist m
=
 
       
[ for i in 1..m do yield r.NextDouble() ]
 
    matrix
([1..n] |> List.map (fun x-> ranlist m))
 
 
// is square matrix
 
let issqr
(m:matrix) =
 
    let n
, m = m.Dimensions
 
    n
=

 
// is postive definite
 
let ispd m
=
 
   
if not (issqr m) then false
 
   
else
 
        let m1
=
mat2dnmat m 
        let qrsolver
= dnAnalytics.LinearAlgebra.Decomposition.Cholesky(m1)
 
        qrsolver
.IsPositiveDefinite()
 
 
// determinant
 
let det m
=
 
    let m1
=
mat2dnmat m 
    let lusolver
= dnAnalytics.LinearAlgebra.Decomposition.LU(m1)
 
    lusolver
.Determinant ()
 
 
// is full rank
 
let isfull m
=
 
    let m1
=
mat2dnmat m 
    let qrsolver
= dnAnalytics.LinearAlgebra.Decomposition.GramSchmidt(m1)
 
    qrsolver
.IsFullRank()
 
 
// rank
 
let rank m
=
 
    let m1
=
mat2dnmat m 
    let svdsolver
= dnAnalytics.LinearAlgebra.Decomposition.Svd(m1, false)
 
    svdsolver
.Rank()
 
 
// inversion by lu
 
let inv m
=
 
    let m1
=
mat2dnmat m 
    let lusolver
= dnAnalytics.LinearAlgebra.Decomposition.LU(m1)
 
    lusolver
.Inverse()
 
 
// lu
 
let lu m
=
 
    let m1
=
mat2dnmat m 
    let lusolver
= dnAnalytics.LinearAlgebra.Decomposition.LU(m1)
 
    let l
= dnmat2mat (DenseMatrix (lusolver.LowerFactor ()))
 
    let u
= dnmat2mat (DenseMatrix (lusolver.UpperFactor ()))
 
   
(l,u)
 
 
// qr
 
let qr m
=
 
    let m1
=
mat2dnmat m 
    let qrsolver
= dnAnalytics.LinearAlgebra.Decomposition.GramSchmidt(m1)
 
    let q
= dnmat2mat (DenseMatrix (qrsolver.Q()))
 
    let r
= dnmat2mat (DenseMatrix (qrsolver.R()))
 
   
(q, r)
 
 
// svd
 
let svd m
=
 
    let m1
=
mat2dnmat m 
    let svdsolver
= dnAnalytics.LinearAlgebra.Decomposition.Svd(m1, true)
 
    let u
= dnmat2mat (DenseMatrix (svdsolver.U()))
 
    let w
= dnmat2mat (DenseMatrix  (svdsolver.W()))
 
    let vt
= dnmat2mat (DenseMatrix (svdsolver.VT()))
 
   
(u, w, vt.Transpose)
 


// and test code
(* todo: read matrix market format   ref: http://math.nist.gov/MatrixMarket/formats.html *)
 
let readmat
(filename:string) =
 
   
System.IO.File.ReadAllLines(filename) |> Array.map (fun x-> (x |> String.split [' '] |> List.toArray |> Array.map float))
 
   
|>
matrix 
 
let timeit f str
=
 
    let watch
= new System.Diagnostics.Stopwatch()
 
    watch
.Start()
 
    let res
= f()
 
    watch
.Stop()
 
    printfn
"%s Needed %f ms" str watch.Elapsed.TotalMilliseconds
 
    res 
 

let test
() =  
    let testlu
() =  
       
for i=1 to 10 do 
            let a
,b = lu (randmat 1000 1000) 
           
() 
       
() 

    let testsvd
() = 
       
for i=1 to 10 do 
            let u
,w,v = svd (randmat 300 300) 
           
() 
       
() 

    let testdet
() = 
       
for i=1 to 10 do 
            let d
= det (randmat 650 650) 
           
() 
       
() 

    timeit testlu
"lu"  
    timeit testsvd
"svd" 
    timeit testdet
"det" 



1. 우선 위의 소스를 그대로  컴파일하였다.

컴파일하니 아래와 같이 에러가 뜬다.
 
D:\test\f#>fsc TestFSharpMatrix.fsx
Microsoft (R) F# 2.0 Compiler build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

TestFSharpMatrix.fsx(106,85): error FS0039: The field, constructor or member 'sp
lit' is not defined


2. 파일 확장명 바꾸고, #r 디렉티브 수정하기

dll 파일을 현재 디렉토리에 놓고 컴파일하기 위해 소스 선두의 #r 디렉티브를 수정하였다.
파일 확장명도 fsx로 바꾸었다.


// 1차 수정된 파일명: TestFSharpMatrix.fsx (소스의 선두 #r 디렉티브 부분 수정)

#r @".\dnAnalytics.dll" 
#r @".\FSharp.PowerPack.dll"
 
 
open dnAnalytics.LinearAlgebra 
open
Microsoft.FSharp.Math
 
open dnAnalytics
.LinearAlgebra.Decomposition
 
 

// 이하 생략



컴파일하면 이전과 동일한 에러메세지가 뜬다,

D:\test\f#>fsc TestFSharpMatrix.fsx
Microsoft (R) F# 2.0 Compiler build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

TestFSharpMatrix.fsx(106,85): error FS0039: The field, constructor or member 'sp
lit' is not defined



3. FSharp.PowerPack.Compatibility.dll 도 사용하자.

F# Power Pack 의  FSharp.PowerPack.Compatibility.dll 을 현재 디렉토리에 넣어 준다.


// 2차 수정된 파일명: testFShapMatrix.fsx (FSharp.PowerPack.Compatibility.dll 을 #r 리렉티브에 추가)

#r @".\dnAnalytics.dll"
#r @".\FSharp.PowerPack.dll"
#r @".\FSharp.PowerPack.Compatibility.dll"

open dnAnalytics.LinearAlgebra 
open
Microsoft.FSharp.Math
 
open dnAnalytics
.LinearAlgebra.Decomposition
 
 
// 이하 생략



2차 수정된 소스는 컴파일은 되지만 실행 결과가 없다.

D:\test\f#>fsc TestFSharpMatrix.fsx
Microsoft (R) F# 2.0 Compiler build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

TestFSharpMatrix.fsx(136,1): warning FS0988: Main module of program is empty: no
thing will happen when it is run


4, 실행위한 Main 모듈을 추가하자.

// 3차 수정된 파일명: testString.fsx (소스의 7째 줄 Split을 String.split로 수정)
// 3차 수정된 파일명: testFShapMatrix.fsx (FSharp.PowerPack.Compatibility.dll 을 #r 리렉티브에 추가)

#r @".\dnAnalytics.dll"
#r @".\FSharp.PowerPack.dll"
#r @".\FSharp.PowerPack.Compatibility.dll";;

open dnAnalytics.LinearAlgebra 
open
Microsoft.FSharp.Math
 
open dnAnalytics
.LinearAlgebra.Decomposition
 
 
// 중략

    timeit testlu
"lu"  
    timeit testsvd
"svd" 
    timeit testdet
"det" 

[<EntryPoint>]
let main args =
    test()
    0           // Return 0. This indicates success.



이제는 컴파일도 잘 되고, 실행도 잘 된다.
실행 후 잠시 기다리면 실행에 소요된 시간이 밀리초 단위로 컨솔에 출력된다.

D:\test\f#>fsc TestFSharpMatrix.fsx
Microsoft (R) F# 2.0 Compiler build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

D:\test\f#>TestFSharpMatrix
lu Needed 21519.869700 ms
svd Needed 6146.898400 ms
det Needed 4221.604900 ms



* 이로서 이 글의 선두에 적어 놓은 목적이 해결되었다.



Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.


Posted by Scripter
,