From an online example I was able to switch from a seq to an array and get the proper syntax.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    type MyFSDistance(source:seq<float>, target:seq<float>) = class

      let sq x = x * x
      let acc = 0

      member x.Source = source
      member x.Target = target
      member x.Acc    = acc

      // Euclidean distance between 2 vectors
      member x.Dist (V1: float[]) V2 =
        Array.zip V1 V2
          |> Array.map(fun (v1, v2) -> (v1 - v2) * (v1 - v2))
          |> Array.sum

    end

By on 1/30/2013 10:39 AM ()

Building on the work, I have a class created with an initial seed array. Then I can use distance to calculate the difference between the initial array and a calling array. I posting the progress in case I'm moving in the wrong direction:

1
2
3
4
5
6
7
8
9
10
11
12
        Dim VBarray(10) As Double
        Dim VBarray2(10) As Double
        For idx = 0 To VBarray.Count - 1
            VBarray(idx) = 1.0
            VBarray2(idx) = 3.0
        Next

        Dim objFSDistance As New FCSDataLibrary.FCSData.MyFSDistance(VBarray)

        Dim dist = objFSDistance.Dist(VBarray2)
        Dim dist2 = objFSDistance.Dist2(VBarray, VBarray2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Initialize a seed array when an instance of the class is created
    type MyFSDistance(source:float[]) = class

      let sq x = x * x
      let acc = 0

      member x.Source = source
      member x.Acc    = acc
      member x.Seeds = seq { for a in 1.0 .. 10.0 do yield a, a, a }
      member x.OneSeed = [|0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.|]
      member x.SeedArray = Seq.toArray x.Seeds 

      // Euclidean distance between 2 vectors
      member x.Dist (V1: float[])  =
        Array.zip V1 x.Source
          |> Array.map(fun (v1, v2) -> (v1 - v2) * (v1 - v2))
          |> Array.sum

      // Euclidean distance between 2 vectors
      member x.Dist2 (V1: float[]) V2 =
        Array.zip V1 V2
          |> Array.map(fun (v1, v2) -> (v1 - v2) * (v1 - v2))
          |> Array.sum

    end

The results of dist = dist2 (both 44), so the code appears to work with the class holding a static seed array.

Next I'll work on creating a list of seed arrays and find the closest to the given array.

1
2
3
objFSDistance.AddSeed(VBarray3)
dim closest = objFSDistance.Closest(VBarray2)

dgp

By on 1/30/2013 11:47 AM ()

I decided to make the VB / F# test a little more practical while testing. The F# portion will hold an RGB color hash. The VB section will initialize and add to the hash, then find a nearest color to an RGB input. I have an error in the ColorLoop, however.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        Dim GreenYellow() As Double = {173, 255, 47}
        Dim Orange() As Double = {255, 127, 0}
        Dim Lavender() As Double = {230, 230, 250}
        Dim Magenta() As Double = {255, 0, 255}
        Dim DarkGoldenRod() As Double = {184, 134, 11}


        Dim objFSDistance As New FCSDataLibrary.FCSData.MyFSColorTable("GreenYellow", GreenYellow)
        objFSDistance.AddEntry("Lavender", Lavender)
        objFSDistance.AddEntry("Orange", Orange)

        Dim test() As Double = {122, 122, 122}
        Dim near = objFSDistance.ColorLoop(test)

        Dim name = objFSDistance.Dist(Magenta)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
    type MyFSColorTable(name: string, rgb:float[]) = class

      let myHash = Hashtable()

      member x.One name rgb = if ( not(myHash.ContainsKey(name)) ) then myHash.Add(name,rgb)
      member x.Name   = name
      member x.RGB = rgb

      // Euclidean distance between 2 vectors
      member x.Dist (V1: float[])  =
        Array.zip V1 x.RGB
          |> Array.map(fun (v1, v2) -> (v1 - v2) * (v1 - v2))
          |> Array.sum

      // Euclidean distance between 2 vectors
      member x.Dist2 (V1: float[]) V2 =
        Array.zip V1 V2
          |> Array.map(fun (v1, v2) -> (v1 - v2) * (v1 - v2))
          |> Array.sum

      member x.ColorLoop (R1: float[]) c =
        for i in myHash.Keys  do
          let near = (x.Dist2 (float [](myHash(i))) R1)
          
      // Euclidean distance between 2 vectors
      member x.AddColor (N1: string) (R1: float[]) = (name, rgb)

      member x.RGBHash = myHash
//      member x.AddEntry (name:string) (rgb: float[]) = (fun k v -> myHash.Add(k, v))
      member x.AddEntry (name:string) (rgb: float[]) = x.One name rgb

    end

Any insight would be appreciated.

dgp

By on 1/30/2013 1:50 PM ()

I have a working solution for a VB to F# interface test. I decided not to use a HashTable, as that structure is only required in the F# portion and a list and record work just fine. The code provides a color table in an F# class and allows the VB interface to create, append and search the color table. Any input into alternative syntax would be appreciated.

VB Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        Dim GreenYellow() As Double = {173, 255, 47}
        Dim Orange() As Double = {255, 127, 0}
        Dim Lavender() As Double = {230, 230, 250}
        Dim Magenta() As Double = {255, 0, 255}
        Dim DarkGoldenRod() As Double = {184, 134, 11}

        Dim test() As Double = {122, 122, 122}

        Dim objFSDistance As New FCSDataLibrary.FCSData.MyFSColorTable("GreenYellow", GreenYellow)
        objFSDistance.AddEntry("Lavender", Lavender)
        objFSDistance.AddEntry("Orange", Orange)
        objFSDistance.AddEntry("Magenta", {255, 0, 255})
        objFSDistance.AddEntry("DarkGoldenRod", {184, 134, 11})

        Dim name = objFSDistance.ColorLoop(test)

ColorLoop return DarkGoldenRod as the closest color match.

FSharp Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    type MyColor = 
      { Name: string;
        Values: float[];
        }

    type MyFSColorTable(name: string, rgb:float[]) = class

      let mutable myHash = Hashtable()
      let mutable CurName = name
      let mutable CurDist = 0.0

      let mutable CurColor = 
        { Name = name;
          Values = rgb;
          }

      let mutable CurList = [CurColor]
     
      member x.AddColor name rgb = CurList <- List.append CurList [{Name = name; Values = rgb}]
      member x.Name   = name

      // Euclidean distance between 2 vectors
      member x.Dist (V1: float[]) V2 =
        Array.zip V1 V2
          |> Array.map(fun (v1, v2) -> (v1 - v2) * (v1 - v2))
          |> Array.sum

      // Loop thru color hash and find the nearest match
      member x.ColorLoop (R1: float[]) = 
        let mutable mindist = x.Dist R1 CurList.Head.Values
        let mutable name =  CurList.Head.Name
        for i in (CurList)  do 
          let mutable s = 0.0 
          s <- x.Dist R1 i.Values
          if s < mindist then 
            mindist <- s
            name <- i.Name
        name
                
      // RGB Hash Table
      member x.RGBHash = myHash
//      member x.AddEntry (name:string) (rgb: float[]) = (fun k v -> myHash.Add(k, v))
      member x.AddEntry (name:string) (rgb: float[]) = x.AddColor name rgb

    end

By on 1/31/2013 11:25 AM ()

Revised F# code from suggestions from Code Review.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    type MyFSColorTable() = 

      // Mutable Color Table will be defined on-the-fly
      let mutable ColorTable = []
      // Euclidean distance between 2 vectors - float is overkill here
      static let Dist (V1: float[]) V2 =
        Array.zip V1 V2
          |> Array.map (fun (v1, v2) -> pown (v1 - v2) 2)
//          |> Array.map(fun (v1, v2) -> (v1 - v2) * (v1 - v2))
          |> Array.sum
     
//    Add new colors to the head of the ColorTable
      member x.AddColor name rgb = ColorTable <- {Name = name; Values = rgb}::ColorTable

//    Find nearest color by calculating euclidean distance of all colors, 
//    then calling List.minBy for the smallest 
      member x.FindNearestColor (rgb : float[]) =
        let nearestColor =
          ColorTable |> List.minBy (fun color -> Dist rgb color.Values)
        nearestColor.Name

      // Obsolete -- Looping thru ColorTable in this original attempt is too imperitive.
      member x.FindNearestColorII (rgb: float[]) = 
        let mutable mindist = Dist rgb ColorTable.Head.Values
        let mutable name =  ColorTable.Head.Name
        for i in (ColorTable)  do 
          let mutable s = 0.0 
          s <- Dist rgb i.Values
          if s < mindist then 
            mindist <- s
            name <- i.Name
        name
                
//      Add an entry to the color table
      member x.AddEntry (name:string) (rgb: float[]) = x.AddColor name rgb
By on 2/4/2013 9:08 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper