Generating Python Code for Matrix Inner Product in SQLite Database
Pada waktu event wordcampid yang lalu saya sempat menulis kode untuk melakukan pencarian citra dari database (image retrieval). Kodenya ditulis ketika agak senggang atau ketika topik pembicaraannya tidak terlalu menarik. Saya menggunakan fitur berupa matriks 8×8 yang disimpan dalam database SQLite. Pada intinya saya berniat melakukan inner (dot) product melalui pernyataan SQL (supaya sekalian diurutin dan dibatasi top N
). Awalnya senang-senang saja, lama-lama saya bosan juga kalau harus mengetik 64 field dan 64 parameter untuk setiap fungsi (ada 3 fungsi yaitu mendefinisikan table, insert, dan find). jadi totalnya 64 x 5 = 320 field harus saya ketik manual. Saya tidak pakai perulangan karena malas melihat kode berisi penempelan string kala itu. Hari berikutnya akhirnya saya menulis kode untuk mengotomatisasi pekerjaan tersebut (bayangkan kalau saya ubah eksperimennya jadi fitur berukuran 12×12 atau 25×25).
Kode yang saya tulis ketika dijalankan akan menghasilkan file teks berisi kode python yang spesifik dengan dimensi matriks yang menjadi parameter.
def genmat(la):
result = []
for i in xrange(0,la[0]):
if len(la)==1:
result += [["%s" % i]]
else:
row = ["%s" % i]
tmp = genmat(la[1:])
for x in tmp:
result += [row+x]
return result
def setup(n, output="Test", tablename="vec", cols=[], classprefix="DocSearch"):
classname=classprefix+output
fpy = open(output+".py", "w")
if len(cols)==0:
cols = [("id", "INTEGER PRIMARY KEY"), ("desc", "CHAR(255)")]
lcols = []
try:
dim = len(n)
vcols = genmat(n)
except:
dim = 1
vcols = genmat([n])
for f in vcols:
lcols += [("v"+"_".join(f), "DOUBLE NOT NULL")]
scols = ", ".join(["%s %s" % (c, t) for c, t in lcols+cols])
fpy.write("""
import sqlite3
class %s:
def __init__(self, dbname="db%s.db"):
self.db = dbname
self.con = sqlite3.connect(self.db)
def setup(self):
self.con.execute("CREATE TABLE %s (%s)")
self.con.commit()
""" % (classname, output, tablename, scols))
acols = ", ".join(["%s" % (c) for c, t in cols])
icols = ", ".join(["%s" % (c) for c, t in lcols+cols])
ivcols = ", ".join(["?"]*(len(lcols)+len(cols)))
_ipcols = []
for f in vcols:
_ipcols += ["f"+"".join(["["+v+"]" for v in f])]
ipcols = ", ".join(_ipcols)
fpy.write("""
def insert(self, f, %s):
self.con.execute("INSERT INTO %s (%s) VALUES (%s)" %s (%s, %s))
self.con.commit()
""" % (acols, tablename, icols, ivcols, "%", ipcols, acols))
qcols = ", ".join(["%s*%s" % (c, "?") for c, t in lcols])
fpy.write("""
def query(self, f):
c = self.con.cursor()
c.execute("SELECT (%s) as dot, %s FROM %s ORDER BY dot DESC" %s (%s))
rows = c.fetchall()
return rows
""" % (qcols, acols, tablename, "%", ipcols))
fpy.write("""
if __name__=="__main__":
search = %s()
search.setup()
""" % (classname))
fpy.close()
if __name__=="__main__":
setup(3, "1x3")
setup([2,2], "2x2")
setup([8,8], "8x8")
#print genmat([2,2])
Kode di atas juga berisi contoh penggunaan fungsi untuk berbagai dimensi (misal 1xn, mxn, mxnxsxtx…xz). Contoh keluaran untuk matriks 2×2 seperti berikut:
import sqlite3
class DocSearch2x2:
def __init__(self, dbname="db2x2.db"):
self.db = dbname
self.con = sqlite3.connect(self.db)
def setup(self):
self.con.execute("CREATE TABLE vec (v0_0 DOUBLE NOT NULL, v0_1 DOUBLE NOT NULL, v1_0 DOUBLE NOT NULL, v1_1 DOUBLE NOT NULL, id INTEGER PRIMARY KEY, desc CHAR(255))")
self.con.commit()
def insert(self, f, id, desc):
self.con.execute("INSERT INTO vec (v0_0, v0_1, v1_0, v1_1, id, desc) VALUES (?, ?, ?, ?, ?, ?)" % (f[0][0], f[0][1], f[1][0], f[1][1], id, desc))
self.con.commit()
def query(self, f):
c = self.con.cursor()
c.execute("SELECT (v0_0*?, v0_1*?, v1_0*?, v1_1*?) as dot, id, desc FROM vec ORDER BY dot DESC" % (f[0][0], f[0][1], f[1][0], f[1][1]))
rows = c.fetchall()
return rows
if __name__=="__main__":
search = DocSearch2x2()
search.setup()
Kode di atas masih bisa dikembangkan lagi, misalnya untuk interface basisdata lain seperti mysql atau postgreS atau menggunakan SQLAlchemy. Oya, saya juga lupa, kode untuk Update belum ada
.
Filed under: computer vision, mathematics, programming | Leave a Comment
Tag:code generation, image retrieval, python
No Responses Yet to “Generating Python Code for Matrix Inner Product in SQLite Database”