`
fanzy618
  • 浏览: 20290 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

用sqlite3实现稀疏矩阵

阅读更多
用python实现了一个稀疏矩阵。
基本思想是3元组(行坐标、列坐标和值)描述矩阵。
将3元组保存在sqlite3的内存表里。

代码如下:
import sqlite3
class SparseMatrix:
    def __init__(self, row_count=2147483647, column_count=2147483647):
        self.db = sqlite3.connect(":memory:")
        self.db.execute("CREATE TABLE 'matrix' ('x' integer, 'y' integer, 'value' real, primary key('x', 'y'));")
        self.row = row_count
        self.column = column_count
    
    def __del__(self):
        self.db.close()
    
    def __getitem__(self, index):
        if isinstance(index, tuple):
            if len(index) == 2:
                row,column = index
                if row >= self.row or column >= self.column:
                    raise IndexError
                cursor = self.db.execute("select value from matrix where x=? and y=?", index)
                value = cursor.fetchone()
                if value:
                    return value[0]
                else:
                    return 0.0
            else:
                raise IndexError
        else:
            raise TypeError
    
    def __setitem__(self, index, value):
        row, column = index
        if row >= self.row or column >= self.column:
            raise IndexError
        self.db.execute("insert or replace into matrix values(?,?,?)", (row, column, value))
    
    def __add__(self, other):  #self + other
        if isinstance(other, SparseMatrix):
            m = self.copy()
            for r,c,v in other:
                m[r,c] = self[r,c] + v
            m.update()
            return m
        else:
            raise TypeError
    
    def __iadd__(self, other): #self += other
        if isinstance(other, SparseMatrix):
            if self.row != other.row or self.column != other.column:
                raise IndexError
            for row,column,value in other:
                self[row,column] = self[row,column] + value
            self.update()
            return self
        else:
            raise TypeError
    
    def __sub__(self, other):
        if isinstance(other, SparseMatrix):
            if self.row != other.row or self.column != other.column:
                raise IndexError
            m = self.copy()
            for r,c,v in other:
                m[r,c] = self[r,c] - v
            m.update()
            return m
        else:
            raise TypeError
    
    def __mul__(self, other):
        if isinstance(other, SparseMatrix):
            m = SparseMatrix(self.row, other.column)
            rows = self.getallrows()
            columns = other.getallcolumns()
            results = []
            data = []
            col_data = other.getcolumn(0)
            for r in rows:
                row_data = self.getrow(r)
                for c in columns:
                    col_data = other.getcolumn(c)
                    pr = row_data.__iter__()
                    pc = col_data.__iter__()
                    rdata = pr.next()
                    cdata = pc.next()
                    while True:
                        try:
                            if rdata[0] == cdata[0]:
                                results.append(rdata[1] * cdata[1])
                                rdata = pr.next()
                                cdata = pc.next()
                            else:
                                if rdata[0] > cdata[0]:
                                    cdata = pc.next()
                                else:
                                    rdata = pr.next()
                        except StopIteration:
                            if results:
                                m[r,0] = sum(results)
                                results = list()
                            break
            m.update()
            return m
        elif isinstance(other, int) or isinstance(other, float):
            m = SparseMatrix(self.row, self.column)
            for r,c,v in self:
                m[r,c] = v * other
            m.update()
            return m
        else:
            raise TypeError
    
    def __iter__(self):
        cursor = self.db.execute("select x,y,value from matrix order by x,y")
        for cell in cursor:
            yield cell
    
    def __len__(self):
        cursor = self.db.execute("select count(*) from matrix")
        return cursor.fetchone()[0]
        
    def insert(self, cells):
        for row,column,value in cells:
            self[row, column] = value
        self.update()
    
    def copy(self):
        m = SparseMatrix(self.row, self.column)
        for r,c,v in self:
            m[r,c] = v
        return m
        
    def getrow(self, row):
        cursor = self.db.execute("select y,value from matrix where x=%d order by y" % row)
        return cursor.fetchall()
    
    def getcolumn(self, column):
        cursor = self.db.execute("select x,value from matrix where y=%d order by x" % column)
        return cursor.fetchall()
    
    def getallrows(self):
        rows = self.db.execute("select distinct x from matrix order by x").fetchall()
        return zip(*rows)[0]
    
    def getallcolumns(self):
        columns = self.db.execute("select distinct y from matrix order by y").fetchall()
        return zip(*columns)[0]
    
    def update(self):
        self.db.execute("DELETE FROM matrix where value between -0.0000001 and 0.0000001")
        self.db.commit()
        

支持下表访问,支持矩阵的加法,减法和乘法运算,支持遍历。
如:
m1 = SparseMatrix()
m2 = SparseMatrix()
m1[0,0] = 1
m2[1,1] = 2
m = m1 + m2
for row,column,value in m:
    print row,column,value


只是实现里功能,速度方面就比较头疼了。
做一个NxN的矩阵与N维向量的乘法用了大于6个小时(N=520000)。
还有一个支持多CPU并行乘法的版本,写的太难看,就不贴出来了。

不过有一个优点是不需要明确的知道矩阵的大小,在某些情况下还是有一些用处吧,我想。
分享到:
评论
4 楼 zxzheaven 2009-09-17  
如果有注释就更好了,这个适用于哪些方面?
3 楼 mathgl 2009-08-19  
python 不是有个 scipy的东西么。。怎么还要劳烦sqlite呢?
2 楼 fanzy618 2009-07-30  
主要是为了做乘法的时候比较方便。
其他的不管怎么保存都需要反复遍历才能完成乘法。

而且我实在没有想出用Python实现十字链表的方法。
1 楼 phyeas 2009-07-29  
为啥要把数据保存到sqlite?

相关推荐

    课程设计基于python+pyqt5+sqlite3实现的图书信息管理系统源码+详细注释.zip

    课程设计基于python+pyqt5+sqlite3实现的图书信息管理系统源码+详细注释.zip课程设计基于python+pyqt5+sqlite3实现的图书信息管理系统源码+详细注释.zip课程设计基于python+pyqt5+sqlite3实现的图书信息管理系统源码...

    sqlite3文件(sqlite3.dll,sqlite3.h,sqlite3.lib)

    标题提到的"sqlite3文件"主要包括三个关键组成部分:`sqlite3.dll`、`sqlite3.h`和`sqlite3.lib`,它们在开发和运行使用SQLite3的应用程序时起着至关重要的作用。 1. `sqlite3.dll`: 这是一个动态链接库文件,通常...

    sqlite3.h、sqlite3.lib、sqlite3.dll

    在开发过程中,使用`sqlite3.h`、`sqlite3.lib`和`sqlite3.dll`可以轻松地将SQLite集成到你的项目中,为你的应用程序提供可靠的数据库支持。记得在使用过程中注意版本兼容性、线程安全和资源管理,以确保程序的稳定...

    sqlite3 加密实现源码

    1. **加密库选择**:在SQLite3中实现加密通常需要引入第三方加密库,如SQLCipher或SQLite Encryption Extension (SEE)。这些库提供了对数据库文件进行加解密的功能,并且它们都基于知名的加密算法,如AES(高级加密...

    Sqlite3重编译版本,支持Sqlite3_key和Sqlite3_rekey方法.rar

    使用`Sqlite3_key`,开发人员可以为每个数据库实例设置不同的密钥,实现更精细的安全控制。 `Sqlite3_rekey`方法则是在数据库已经存在并已用特定密钥加密的情况下,更改加密密钥的功能。这在需要更新安全策略或者...

    Delphi使用ASqlite3 连接SQLite上例子

    本教程将详细讲解如何在Delphi环境中使用ASqlite3控件连接并操作SQLite数据库。ASqlite3是一款专门为Delphi开发者设计的SQLite数据库接口组件,它使得在Delphi程序中与SQLite数据库交互变得简单。 首先,我们需要...

    sqlite3.lib sqlite3.h sqlite3.dll sqlite3.exe

    这个压缩包包含了SQLite3的关键组件,分别是`sqlite3.lib`、`sqlite3.h`、`sqlite3.dll`和`sqlite3.exe`,它们在开发和运行使用SQLite3的应用程序时起着至关重要的作用。 `sqlite3.lib`是SQLite3的静态链接库文件,...

    winform连接sqlite3登陆功能实现

    在本文中,我们将深入探讨如何在Windows Forms(WinForm)应用程序中实现SQLite3数据库的登录功能。SQLite3是一种轻量级、开源的嵌入式数据库,适用于桌面应用、移动设备和分布式系统。它无需单独的服务器进程,可以...

    使用sqlite3的类库和.h文件

    使用sqlite3的类库和头文件,开发者可以在C++项目中轻松实现数据库操作。理解并熟练运用这些基本操作,能帮助你在项目中构建强大的数据存储和检索功能。不过,这只是SQLite3功能的冰山一角,更深入的使用还包括...

    Linux-sqlite3

    7. **存储过程**:虽然SQLite3不直接支持存储过程,但可以通过VFS(Virtual File System)机制实现类似的功能。 **交叉编译SQLite3** 当需要将SQLite3应用于不同的架构,比如从x86到嵌入式ARM设备,就需要进行交叉...

    Sqlite3 安装文件

    在这个“Sqlite3 安装文件”压缩包中,包含了 SQLite3 的安装程序及相关文档,便于用户在自己的操作系统上进行安装和使用。 首先,让我们详细了解一下 SQLite3 的主要特点: 1. **轻量级**:SQLite3 不需要独立的...

    可加密的Sqlite3.dll和Sqlite3.lib

    Sqlite3.dll和Sqlite3.lib是SQLite数据库引擎的动态链接库(DLL)和静态库文件,用于在Windows操作系统上实现SQLite的功能。SQLite是一个轻量级的、自包含的、无服务器的、事务性的SQL数据库引擎,广泛应用于嵌入式...

    用sqlite实现学生成绩数据库的增删改查用sqlite实现学生成绩数据库的增删改查用sqlite实现学生成绩数据库的增删改查用sqlite实现学生成绩数据库的增删改查用sqlite实现学生成绩数据库的增删改查用sqlite实现学生成绩数据库的增删改查

    用sqlite实现学生成绩数据库的增删改查用sqlite实现学生成绩数据库的增删改查用sqlite实现学生成绩数据库的增删改查用sqlite实现学生成绩数据库的增删改查用sqlite实现学生成绩数据库的增删改查用sqlite实现学生成绩...

    sqlite3_key

    加密过程应该在不影响 SQLite3 API 使用的前提下透明地进行,也就是说,开发人员应该能像处理普通无加密的 SQLite3 数据库一样操作加密数据库。 在实际应用中,除了设置数据库密钥,还需要考虑其他安全措施,如: 1...

    MFC 使用sqlite3 例子

    在本文中,我们将深入探讨如何在Microsoft Foundation Class (MFC) 应用程序中使用SQLite3数据库引擎。这个示例项目是使用Visual Studio 2010开发的,它演示了MFC对话框中对SQLite数据库的基本操作,包括添加、删除...

    SQLite3 API编程手册.pdf

    SQLite 提供了加密数据库的功能,可以使用 sqlite3_key 和 sqlite3_rekey 函数来实现数据库加密。 后记 SQLite 是一个小巧、轻量级的关系数据库管理系统,提供了一个灵活的解决方案,可以满足各种应用场景的需求...

    SQLite3C++

    在本主题中,我们关注的是SQLite3与C++的结合,即如何在C++程序中使用SQLite3进行数据存储和检索。 1. **SQLite3的特性** - **轻量级**: SQLite3数据库文件是一个普通的文件,可以在文件系统中直接创建、读取和...

    SQLite3 支持sqlite3-key() sqlite3-rekey()

    免费版sqlite不带加解密功能,这个wssqlite实现了加解密数据库的功能,网上好多都是不能编译成功的,所以作者编译后,可以直接使用该资源,包含(sqlite3.h,sqlite3.lib,sqlite2.dll,sqlite3userauth.h)

    Sqlite3和管理工具

    这意味着,当你在使用SQLite3时,数据库文件实际上就是一个普通的磁盘文件,可以随应用程序一起复制和移动。 SQLite3的核心特性包括: 1. **事务性**:SQLite3支持ACID(原子性、一致性、隔离性、持久性)事务,...

Global site tag (gtag.js) - Google Analytics