Complete Correlation Matrix Memories (CCMM) Implementation
d:todo
• paragraph
• description
• paragraph
• test of all properties that are described in Teuvo's paper
• paragraph
• abstract class which can also be used in order to implement the incomplete correlation matrix memory
• paragraph
• mutable version where values can be added and removed
• paragraph
• back end agnostic repository system
• paragraph
• repository distribution system
• paragraph
• Move this and related articles to a new project.
#!/usr/bin/env python3
"""This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.

Based on the paper "Correlation Matrix Memories" by TEUVO KOHONEN.
"""
__author__ = 'Mārtiņš Avots'
from testingArtifacts import floatTuple
import unittest
class CompleteCorrelationMatrixMemory():
def __init__(self, keyValuePairs):
for key in keyValuePairs:
self.columns = len(key)
self.rows = len(keyValuePairs[key])
break
self.matrix = [[0. for i in range(self.columns)] for j in range(self.rows)]
keyValuePairs = self.convertKeyValuePairs(keyValuePairs)
for iRow in range(self.rows):
for iColumn in range(self.columns):
for key in keyValuePairs:
c = self.c(key) # Deviation from TEUVO's paper
value = keyValuePairs[key]
self.matrix[iRow][iColumn] += c * key[iColumn] * value[iRow]
def convertKeyValuePairs(self, keyValuePairs):
rVal = dict()
for key in keyValuePairs:
value = keyValuePairs[key]
key = tuple(floatTuple(key))
value = floatTuple(value)
rVal[key] = value
return rVal
def c(self, vector):
rBase = 0.
for i in vector:
rBase += i ** 2
return 1. / rBase
def recall(self, key):
key = floatTuple(key)
value = [0.]*self.rows
for iRow in range(len(value)):
for iColumn in range(len(key)):
value[iRow]
self.matrix[iRow][iColumn]
key[iColumn]
value[iRow] += self.matrix[iRow][iColumn] * key[iColumn]
return floatTuple(value)
if __name__ == "__main__":
from orthogonalKeyTests import OrthogonalKeyTests
from randomKeyTests import RandomKeyTests
from classificationTests import ClassificationTests
unittest.main()

#!/usr/bin/env python3
"""This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
__author__ = 'Mārtiņš Avots'
from random import uniform, choice
def floatTuple(vector):
rVal = []
for e in vector:
rVal.append(float(e))
return rVal
def difference(a, b):
rVal = 0.
for i in range(len(a)):
rVal += abs(a[i] - b[i])
return rVal
def randomVector(length):
rVal = []
for i in range(length):
rVal.append(
uniform(-1000, 1000) # TODO Random chosen magic constants
)
return rVal
def randomZeroOneVector(length):
rVal = []
for i in range(length):
rVal.append(choice([0,1]))
return rVal
def randomZeroOnePositiveAndNegativeVector(length):
rVal = []
for i in range(length):
rVal.append(choice([-1,0,1]))
return rVal
def printImage(matrix, length):
rows=int(len(matrix) / length)
for row in range(rows):
rowStr = ""
for i in range(length):
rowStr += " " + str(round(matrix[row * length + i], 2))
print(rowStr)
print("")
images3x3 = {
"cross" : (1,0,1, 0,1,0, 1,0,1), # cross
"vertical" : (0,1,0, 0,1,0, 0,1,0), # vertical
"horizontal" : (0,0,0, 1,1,1, 0,0,0), # horizontal
"zero" : (1,1,1, 1,0,1, 1,1,1), # zero
"one" : (0,0,1, 0,1,1, 0,0,1), # one
"v" : (1,0,1, 1,0,1, 0,1,0), # v
"seven" : (1,1,1, 0,1,0, 1,0,0), # seven
"t" : (1,1,1, 0,1,0, 0,1,0), # t
"h" : (1,0,1, 1,1,1, 1,0,1) # h
}

#!/usr/bin/env python3
"""This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.

Based on the paper "Correlation Matrix Memories" by TEUVO KOHONEN.
"""
__author__ = 'Mārtiņš Avots'
import unittest
from completeCorrelationMatrixMemories import CompleteCorrelationMatrixMemory
from testingArtifacts import randomVector, randomZeroOneVector, difference, images3x3, randomZeroOnePositiveAndNegativeVector
from random import uniform, sample
class RandomKeyTests(unittest.TestCase):
def testRandomKeys(self): # TODO This test fails randomly.
self.__randomKeysTest(9, 9, lambda:randomVector(9))
def testRandomZeroOneKeys(self): # TODO This test fails randomly.
self.__randomKeysTest(9, 9, lambda:randomZeroOnePositiveAndNegativeVector(9))
def __randomKeysTest(self, keySize, valueCount, randomKeyGenerator):
values = sample(list(images3x3.values()), valueCount)
mapping = {}
for i in range(valueCount):
tmpRandomVector = tuple(randomKeyGenerator())
while tmpRandomVector in mapping:
tmpRandomxVector = tuple(randomKeyGenerator())
mapping[tmpRandomVector] = values[i]
testSubject = CompleteCorrelationMatrixMemory(mapping)
overallDifference = 0.
for key in mapping:
overallDifference += difference(testSubject.recall(key), mapping[key])
meanDifference = overallDifference / (9 * 9)
print("testRandomKeys: meanDifference = " + str(meanDifference)) # TODO make logs instead of console prints
# Randomly generated vectors are assumed to be not orthogonal.
# TODO check orthogonality during test and change assertions accordingly
self.assertTrue(meanDifference < .6)
self.assertTrue(meanDifference > .4)

#!/usr/bin/env python3
"""This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.

Based on the paper "Correlation Matrix Memories" by TEUVO KOHONEN.
"""
__author__ = 'Mārtiņš Avots'
from completeCorrelationMatrixMemories import CompleteCorrelationMatrixMemory
from unittest import TestCase, expectedFailure
from testingArtifacts import floatTuple, difference, images3x3
class ClassificationTests(TestCase):
# TODO high resolution image tests
def testClassificationOf2Images(self):
self.__testOrthogonalKeys({
images3x3["cross"] : (0,),
images3x3["zero"] : (2,),
})
def testClassificationOf2OtherImages(self):
self.__testOrthogonalKeys({
images3x3["cross"] : (0,),
images3x3["zero"] : (2,),
})
@expectedFailure
def testClassificationOf9Images(self):
"""It is not expected to work, as the keys are most propably not orthogonal"""
self.__testOrthogonalKeys({
images3x3["cross"] : (0,),
images3x3["vertical"] : (1,),
images3x3["horizontal"] : (2,),
images3x3["zero"] : (3,),
images3x3["one"] : (4,)
})
def __testOrthogonalKeys(self, mapping):
testSubject = CompleteCorrelationMatrixMemory(mapping)
for key in mapping:
self.assertEqual(mapping[key], self.__nearestNumber(mapping.values(), testSubject.recall(key)))
def __nearestNumber(self, candidates, number):
"""Candidate is an tuple with 1 element."""
diff = 1000000000 # TODO magic number
candidate = None
for i in candidates:
currentDiff = abs(i - number)
if currentDiff < diff:
diff = currentDiff
candidate = i
return candidate

d:todo
• paragraph
• Implementation