'If you look closely, you can see the letters made out of 1's Private A1 As Integer() = New Integer() {0, 0, 1, 1, 0, 0, 0, _ 0, 0, 0, 1, 0, 0, 0, _ 0, 0, 0, 1, 0, 0, 0, _ 0, 0, 1, 0, 1, 0, 0, _ 0, 0, 1, 0, 1, 0, 0, _ 0, 1, 1, 1, 1, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 1, 1, 1, 0, 1, 1, 1} Private B1 As Integer() = New Integer() {1, 1, 1, 1, 1, 1, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 1, 1, 1, 1, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 1, 1, 1, 1, 1, 1, 0} Private C1 As Integer() = New Integer() {0, 0, 1, 1, 1, 1, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 0, 1, 1, 1, 1, 0} Private D1 As Integer() = New Integer() {1, 1, 1, 1, 1, 0, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 1, 0, _ 1, 1, 1, 1, 1, 0, 0} Private E1 As Integer() = New Integer() {1, 1, 1, 1, 1, 1, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 0, _ 0, 1, 0, 1, 0, 0, 0, _ 0, 1, 1, 1, 0, 0, 0, _ 0, 1, 0, 1, 0, 0, 0, _ 0, 1, 0, 0, 0, 0, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 1, 1, 1, 1, 1, 1, 1} Private J1 As Integer() = New Integer() {0, 0, 0, 1, 1, 1, 1, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 0, 1, 1, 1, 0, 0} Private K1 As Integer() = New Integer() {1, 1, 1, 0, 0, 1, 1, _ 0, 1, 0, 0, 1, 0, 0, _ 0, 1, 0, 1, 0, 0, 0, _ 0, 1, 1, 0, 0, 0, 0, _ 0, 1, 1, 0, 0, 0, 0, _ 0, 1, 0, 1, 0, 0, 0, _ 0, 1, 0, 0, 1, 0, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 1, 1, 1, 0, 0, 1, 1} Private A2 As Integer() = New Integer() {0, 0, 0, 1, 0, 0, 0, _ 0, 0, 0, 1, 0, 0, 0, _ 0, 0, 0, 1, 0, 0, 0, _ 0, 0, 1, 0, 1, 0, 0, _ 0, 0, 1, 0, 1, 0, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 1, 1, 1, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0} Private B2 As Integer() = New Integer() {1, 1, 1, 1, 1, 1, 0, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 1, 1, 1, 1, 1, 0, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 1, 1, 1, 1, 1, 0} Private C2 As Integer() = New Integer() {0, 0, 1, 1, 1, 0, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 0, 1, 1, 1, 0, 0} Private D2 As Integer() = New Integer() {1, 1, 1, 1, 1, 0, 0, _ 1, 0, 0, 0, 0, 1, 0, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 1, 0, _ 1, 1, 1, 1, 1, 0, 0} Private E2 As Integer() = New Integer() {1, 1, 1, 1, 1, 1, 1, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 1, 1, 1, 1, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 1, 1, 1, 1, 1, 1} Private J2 As Integer() = New Integer() {0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 0, 1, 1, 1, 0, 0} Private K2 As Integer() = New Integer() {1, 0, 0, 0, 0, 1, 0, _ 1, 0, 0, 0, 1, 0, 0, _ 1, 0, 0, 1, 0, 0, 0, _ 1, 0, 1, 0, 0, 0, 0, _ 1, 1, 0, 0, 0, 0, 0, _ 1, 0, 1, 0, 0, 0, 0, _ 1, 0, 0, 1, 0, 0, 0, _ 1, 0, 0, 0, 1, 0, 0, _ 1, 0, 0, 0, 0, 1, 0} Private A3 As Integer() = New Integer() {0, 0, 0, 1, 0, 0, 0, _ 0, 0, 0, 1, 0, 0, 0, _ 0, 0, 1, 0, 1, 0, 0, _ 0, 0, 1, 0, 1, 0, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 1, 1, 1, 1, 0, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 1, 0, 0, 0, 1, 1} Private B3 As Integer() = New Integer() {1, 1, 1, 1, 1, 1, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 1, 1, 1, 1, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 1, 1, 1, 1, 1, 1, 0} Private C3 As Integer() = New Integer() {0, 0, 1, 1, 1, 0, 1, _ 0, 1, 0, 0, 0, 1, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 0, 1, 1, 1, 0, 0} Private D3 As Integer() = New Integer() {1, 1, 1, 1, 0, 0, 0, _ 0, 1, 0, 0, 1, 0, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 1, 0, 0, _ 1, 1, 1, 1, 0, 0, 0} Private E3 As Integer() = New Integer() {1, 1, 1, 1, 1, 1, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 1, 0, 0, _ 0, 1, 1, 1, 1, 0, 0, _ 0, 1, 0, 0, 1, 0, 0, _ 0, 1, 0, 0, 0, 0, 0, _ 0, 1, 0, 0, 0, 0, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 1, 1, 1, 1, 1, 1, 1} Private J3 As Integer() = New Integer() {0, 0, 0, 0, 1, 1, 1, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 0, 1, 1, 1, 0, 0} Private K3 As Integer() = New Integer() {1, 1, 1, 0, 0, 1, 1, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 1, 0, 0, _ 0, 1, 0, 1, 0, 0, 0, _ 0, 1, 1, 0, 0, 0, 0, _ 0, 1, 0, 1, 0, 0, 0, _ 0, 1, 0, 0, 1, 0, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 1, 1, 1, 0, 0, 1, 1} Private Const n As Integer = 63 'Number of components in an input vector. Private Const m As Integer = 10 'Max number of clusters to be formed. Private Const VIGILANCE As Double = 0.3 Private Const CR As String = Chr(13) + Chr(10) 'For display purposes. Private Const FONT_WIDTH As Integer = 7 Private TRAINING_PATTERNS As Integer = 21 'How many PATTERNS for training weights. Private Const IN_PATTERNS As Integer = 21 'Total input patterns. Private Pattern As Integer()() = New Integer(IN_PATTERNS)() {} Private bw(m - 1, n - 1) As Double 'Bottom-up weights. Private tw(m - 1, n - 1) As Double 'Top-down weights. Private F1a(n - 1) As Integer 'Input layer. Private F1b(n - 1) As Integer 'Interface layer. Private F2(m - 1) As Double Private Membership(IN_PATTERNS) As Integer Private NotFirstEpoch As Boolean = False Private Sub Initialize() Dim i, j As Integer 'Insert pattern arrays into Pattern() to make an array of arrays. Pattern(0) = A1 Pattern(1) = B1 Pattern(2) = C1 Pattern(3) = D1 Pattern(4) = E1 Pattern(5) = J1 Pattern(6) = K1 Pattern(7) = A2 Pattern(8) = B2 Pattern(9) = C2 Pattern(10) = D2 Pattern(11) = E2 Pattern(12) = J2 Pattern(13) = K2 Pattern(14) = A3 Pattern(15) = B3 Pattern(16) = C3 Pattern(17) = D3 Pattern(18) = E3 Pattern(19) = J3 Pattern(20) = K3 'Initialize bottom-up weight matrix. For i = 0 To m - 1 For j = 0 To n - 1 bw(i, j) = 1 / (1 + n) Next j Next i 'Initialize top-down weight matrix. For i = 0 To m - 1 For j = 0 To n - 1 tw(i, j) = 1.0 Next j Next i End Sub Private Sub ART1() Dim i, j, VecNum, InputSum, ActivationSum, F2Max As Integer Dim Reset As Boolean For VecNum = 0 To IN_PATTERNS - 1 'Initialize F2 layer activations to 0.0 For i = 0 To m - 1 F2(i) = 0.0 Next i 'Input pattern() to F1 layer. For i = 0 To n - 1 F1a(i) = Pattern(VecNum)(i) Next i 'Compute sum of input pattern. InputSum = VectorSum(F1a) 'Compute activations for each node in the F1 layer. 'Send input signal from F1a to the F1b layer. For i = 0 To n - 1 F1b(i) = F1a(i) Next i 'Compute net input for each node in the F2 layer. For i = 0 To m - 1 For j = 0 To n - 1 F2(i) += bw(i, j) * F1a(j) Next j Next i Reset = True Do While Reset = True 'Determine the largest value of the F2 nodes. F2Max = Maximum(F2) 'Recompute the F1a to F1b activations (perform AND function). For i = 0 To n - 1 F1b(i) = F1a(i) * tw(F2Max, i) Next i 'Compute sum of input pattern. ActivationSum = VectorSum(F1b) Reset = TestForReset(ActivationSum, InputSum, F2, F2Max) Loop 'Only use number of TRAINING_PATTERNS for training, the rest are tests. If VecNum < TRAINING_PATTERNS Then UpdateWeights(bw, tw, ActivationSum, F2Max) End If 'Record which cluster the input vector is assigned to. Membership(VecNum) = F2Max Next VecNum End Sub Private Function TestForReset(ByVal ActivationSum As Integer, _ ByVal InputSum As Integer, _ ByRef F2Array As Double(), _ ByVal F2Max As Integer) As Boolean If (ActivationSum / InputSum) >= VIGILANCE Then TestForReset = False 'Candidate is accepted. ElseIf (ActivationSum / InputSum) < VIGILANCE Then F2Array(F2Max) = -1.0 'Inhibit. TestForReset = True 'Candidate is rejected. End If End Function Private Sub UpdateWeights(ByRef bwArray As Double(,), _ ByRef twArray As Double(,), _ ByVal ActivationSum As Integer, _ ByVal F2Max As Integer) Dim i, j As Integer 'Update bw(F2Max) For i = 0 To n - 1 bw(F2Max, i) = (2 * F1b(i)) / (1 + ActivationSum) Next i 'Update tw(F2Max) For i = 0 To n - 1 tw(F2Max, i) = F1b(i) Next i End Sub Private Function VectorSum(ByRef NodeArray As Integer()) As Integer Dim i, TempSum As Integer 'Compute sum of input pattern. For i = 0 To n - 1 TempSum += NodeArray(i) Next i VectorSum = TempSum End Function Private Function Maximum(ByRef NodeArray As Double()) As Integer Dim i As Integer Dim Winner As Integer Dim FoundNewWinner As Boolean Dim Done As Boolean = False Winner = 0 Do Until Done FoundNewWinner = False For i = 0 To m - 1 If NodeArray(i) > NodeArray(Winner) Then Winner = i FoundNewWinner = True End If Next i If FoundNewWinner = False Then Done = True End If Loop Maximum = Winner End Function Private Sub PrintResults() Dim i, j, k As Integer Dim TempString As String 'For speed. TempString += "Input vectors assigned to each cluster:" + CR + CR For i = 0 To m - 1 TempString += "Cluster # " + CStr(i) + ": " For j = 0 To IN_PATTERNS - 1 If Membership(j) = i Then TempString += CStr(j) + ", " End If Next TempString += CR Next k = 0 TempString += CR + "Final weight values for each cluster:" + CR + CR For i = 0 To m - 1 For j = 0 To n - 1 If tw(i, j) >= 0.5 Then TempString += "#" Else TempString += "." End If k += 1 If k = FONT_WIDTH Then TempString += CR k = 0 End If Next j TempString += CR Next i Text1.Text = TempString End Sub Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles Button1.Click If NotFirstEpoch = False Then Initialize() 'Initialize variables only at first epoch. NotFirstEpoch = True End If Text1.Clear() ART1() PrintResults() End Sub