목적:
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
,