arduino_rfid_controller / ThreeWireMatrix / rl.py

import itertools,time,sys
from math import sqrt

# This assumes a pin arrangement of:
# GND->a->p1->b->p2->c->p3->d->p4->e->p5->f->p6->g->p7->h->VCC

class AnalogMatrixKeypadSolver:
  def __init__(self,cols,rows,tap):
    self.tap = tap
    self.rows = rows
    self.cols = cols

  def calcResistances(self,resistors):
    ka = {}
    assert len(resistors) == len(self.rows)+len(self.cols)+1
    for r in range(0,len(self.rows)):
      for c in range(0,len(self.cols)):
        key = r*len(self.cols)+c+1
        if self.rows[r] < self.cols[c]:
          a = self.rows[r]
          b = self.cols[c]
        else:
          b = self.rows[r]
          a = self.cols[c]
        totalResistanceList = list(resistors)
        del totalResistanceList[a:b]
        groundResistanceList = list(resistors[0:self.tap])
        del groundResistanceList[a:b]
        ka[key] = {'g':groundResistanceList,'t':totalResistanceList}
    return ka
        
  def printKeyFunctions(self,resistors):
    assert len(resistors) == len(self.rows)+len(self.cols)+1
    rs = self.calcResistances(resistors)
    for r in rs:
      print "k%02i = (%s)/(%s)" % (r,"+".join([str(s) for s in rs[r]['g']]),"+".join([str(s) for s in rs[r]['t']]))

  def printKeyFunctions(self,resistors):
    assert len(resistors) == len(self.rows)+len(self.cols)+1
    rs = self.calcResistances(resistors)
    for r in rs:
      print "k%02i = (%s)/(%s)" % (r,"+".join([str(s) for s in rs[r]['g']]),"+".join([str(s) for s in rs[r]['t']]))

  def printKeyFunctionsSolved(self,resistors):
    assert len(resistors) == len(self.rows)+len(self.cols)+1
    rs = self.calcResistances(resistors)
    for r in rs:
      print "k%02i = (%s)/(%s) = %s" % (r,"+".join([str(s) for s in rs[r]['g']]),"+".join([str(s) for s in rs[r]['t']]),float(sum(rs[r]['g']))/float(sum(rs[r]['t']))*1024)

  def minDiff(self,resistors,m=None):
#    assert len(resistors) == len(self.rows)+len(self.cols)+1,"Expecting %s resistor values, but got %s" % (len(self.rows)+len(self.cols)+1,len(resistors))
    rs = self.calcResistances(resistors)
    numberList = [(float(sum(rs[r]['g']))/float(sum(rs[r]['t'])))*1024 for r in rs]
    if len(set(numberList)) < len(numberList):
      return 0
    a=sorted(numberList)
    b= []
    for x,y in zip(a,a[1:]):
      s = y-x
      if s < m:
        return 0
      b.append(s)
    return int(min(b))
    #return int(min(y-x for x,y in zip(a,a[1:])))
  def printKeyRanges(self,resistors):
    rs = self.calcResistances(resistors)
    numberList = [(float(sum(rs[r]['g']))/float(sum(rs[r]['t'])))*1024 for r in rs]
    for i,r in enumerate(rs):
      print "k%02i = %s" % (r,numberList[i])

  def stdDev(self,resistors):
    assert len(resistors) == len(self.rows)+len(self.cols)+1,"Expecting %s resistor values, but got %s" % (len(self.rows)+len(self.cols)+1,len(resistors))
    rs = self.calcResistances(resistors)
    numberList = [(float(sum(rs[r]['g']))/float(sum(rs[r]['t']))) for r in rs]
    n = len(numberList)
    mean = sum(numberList) / float(n)
    std = 0
    for a in numberList:
      std = std + (a - mean)**2
    std = sqrt(std / float(n-1))
    return std*1024

###############################################################################

TAP_PIN = 3
MATRIX_ROWS = [2,7,6,4]
MATRIX_COLS = [3,1,5]
RESISTORS = [
  560,   # a
  8200,  # b
  18000, # c
  910,   # d
  9100,  # e
  15000, # f
  5100,  # g
  51     # h
]
RESISTORS_NAME = [
  'a',
  'b',
  'c',
  'd',
  'e',
  'f',
  'g',
  'h'
]

def main(args):
  start = 0
  if len(args) > 0:
    start = int(args[0])
  E12 = [1.0, 1.2, 1.5, 1.8, 2.2, 2.7, 3.3, 3.9, 4.7, 5.6, 6.8, 8.2]
  E12C = itertools.product(E12 + [x * 10 for x in E12] + [x * 100 for x in E12] + [x * 1000 for x in E12] + [x * 10000 for x in E12] + [x * 100000 for x in E12] + [x * 1000000 for x in E12] + [x * 10000000 for x in E12], repeat=len(MATRIX_COLS)+len(MATRIX_ROWS)+1)
  E12C = itertools.product(E12 + [x * 10 for x in E12] + [x * 100 for x in E12] + [x * 1000 for x in E12], repeat=len(MATRIX_COLS)+len(MATRIX_ROWS)+1)
  E12C = itertools.permutations([x * 100 for x in E12], len(MATRIX_COLS)+len(MATRIX_ROWS)+1)
  E12C = itertools.permutations([1000,1200,1500,1800,2200,2700,3300,3900,4700,5600,6800,8200], len(MATRIX_COLS)+len(MATRIX_ROWS)+1)
  E12C = itertools.permutations([560,8200,18000,910,9100,15000,5100,51], len(MATRIX_COLS)+len(MATRIX_ROWS)+1)
  E12C = itertools.permutations([x*100 for x in E12] + [x*1000 for x in E12], len(MATRIX_COLS)+len(MATRIX_ROWS)+1)
  amks = AnalogMatrixKeypadSolver(MATRIX_COLS,MATRIX_ROWS,TAP_PIN)
  amks.printKeyFunctions(RESISTORS_NAME)
  amks.printKeyFunctionsSolved([1000, 1200, 10000, 1500, 4700, 8200, 1800, 2200])
  return
  g = 1
  skip = start
  t1 = time.time()
  i = 0
  try:
    for i,p in enumerate(itertools.islice(E12C,skip,None)):
      g1 = amks.minDiff(list(p),g)
      if g1 >= g:
        g = g1
        print i+skip,g,":",list(p)
  except KeyboardInterrupt:
    print
    print "ending on %s" % i
  t2 = time.time()
  #print 'took %0.3f ms' % (((t2-t1)*1000.0)/50000)
  
if __name__ == '__main__':
  main(sys.argv[1:])
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.