如何培养一个存储在第二个功率嵌套词典中的稀疏三角矩阵?

发布于 2025-01-17 20:40:32 字数 1074 浏览 0 评论 0原文

我有一个稀疏的三角矩阵,我需要将其提升到第二个力量。问题是,要求之一是矩阵被存储为嵌套词典(我需要创建Python实现),因此Numpy的标准函数不应用。 (我知道这种存储矩阵的方式可能过于杀伤,但这是对大学课程的

过多的

    def __init__(self, *matrix):
        self.rare_values = dict()
        if len(matrix) > 0:
            for i, line in enumerate(matrix):
                if i == 0:
                    self.n = line
                    continue
                value = line[0]
                i = line[1]
                j = line[2]
                if j > i:

                    i = line[2]
                    j = line[1]
                if i in self.rare_values.keys():
                    if j in self.rare_values[i].keys():
                        self.rare_values[i][j] += value
                    else:
                        dict_column = {j: value}
                        self.rare_values[i].update(dict_column)
                else:
                    dict_line = {i: {j: value}}
                    self.rare_values.update(dict_line)

) 。是否有可能实施算法来提高第二功率的矩阵?如果是这样,如果您可以就我如何处理它提供伪代码或极简主义的解释,我将非常感激。

谢谢你!

I have a sparse triangular matrix that I need to raise to the 2nd power. The problem is, one of the requirements is that the matrix is stored as a nested dictionary (I need to create a python implementation), and so the standard functions from numpy do not apply. (I know this way of storing a matrix is probably overkill, but this is for a university course)

Below is how I've implemented the creation of the matrix itself (rare is the equivalent to sparse here):

    def __init__(self, *matrix):
        self.rare_values = dict()
        if len(matrix) > 0:
            for i, line in enumerate(matrix):
                if i == 0:
                    self.n = line
                    continue
                value = line[0]
                i = line[1]
                j = line[2]
                if j > i:

                    i = line[2]
                    j = line[1]
                if i in self.rare_values.keys():
                    if j in self.rare_values[i].keys():
                        self.rare_values[i][j] += value
                    else:
                        dict_column = {j: value}
                        self.rare_values[i].update(dict_column)
                else:
                    dict_line = {i: {j: value}}
                    self.rare_values.update(dict_line)

My question is, would it be possible to implement an algorithm to raise such a matrix to the 2nd power? If so, I would be more than thankful if you could provide a pseudocode or minimalist explanation as to how I may go about it.

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小耗子 2025-01-24 20:40:32

您提供的代码可以显着简化为:

class Sparse:
    def __init__(self, n=None, *matrix):
        self.rare_values = dict()
        self.n = n
        for line in matrix:
            value, *indices = line
            c,r = sorted(indices)
            # Personally, here I would have instead used
            #   r,c = sorted(indices, reverse=True)
            # as (r,c) order seems more common, but it's no big deal.
            self.rare_values.setdefault(r, {})[c] = value

这会产生与您的 __init__ 方法相同的结构,只是更清晰(IMO)。

从那里开始,对每个值进行平方就像迭代 dict-of-dicts 一样简单,例如使用嵌套的 for 循环迭代 .items()

    def square(self):
        for (r,row) in self.rare_values.items():
            for (c,val) in row.items():
                self.rare_values[r][c] = val ** 2

示例:

class Sparse:
    def __init__(self, n=None, *matrix):
        self.rare_values = dict()
        self.n = n
        for line in matrix:
            value, *indices = line
            c,r = sorted(indices)
            self.rare_values.setdefault(r, {})[c] = value

    def square(self):
        for (r,row) in self.rare_values.items():
            for (c,val) in row.items():
                self.rare_values[r][c] = val ** 2

s = Sparse(3, (0,0,0), (2,1,1), (4,0,2), (6,2,3), (8,0,4))
print(s.rare_values)  # {0: {0: 0}, 1: {1: 2}, 2: {0: 4}, 3: {2: 6}, 4: {0: 8}}
s.square()
print(s.rare_values)  # {0: {0: 0}, 1: {1: 4}, 2: {0: 16}, 3: {2: 36}, 4: {0: 64}}

来自注释的后续操作

下面的示例展示了如何对矩阵求幂(不是我上面展示的按元素运算)。

请注意,此代码更改了您的版本和我的原始版本的一些内容。它接受 (r,c,v) 顺序的项目,并且不会尝试像强制三角矩阵那样“标准化”索引。

如果您想要这种行为,则必须编辑此版本才能将其重新添加回来。

class Sparse:
    def __init__(self, n=None, entries=None):
        self.matrix = dict()
        self.n = n
        for (r,c,v) in (entries or []):
            self.set(r, c, v)

    def set(self, r, c, v):
        self.matrix.setdefault(r, {})[c] = v

    def get(self, r, c):
        return self.matrix.get(r, {}).get(c, 0)

    def square_matrix(self):
        result = Sparse(self.n)
        for r in range(self.n):
            for c in range(self.n):
                val = sum(self.get(r,i) * self.get(i,c) for i in range(self.n))
                result.set(r, c, val)

        return result

sparse = Sparse(2, [
    (0,0,1), (0,1,2),
    (1,0,3), (1,1,4),
])
print(sparse.matrix)   # {0: {0: 1, 1: 2}, 1: {0: 3, 1: 4}}
#                        = [[1 2]
#                           [3 4]]
result = sparse.square_matrix()
print(result.matrix)   # {0: {0: 7, 1: 10}, 1: {0: 15, 1: 22}}
#                        = [[ 7 10]
#                           [15 20]]

The code you provided can be significantly reduced to something like:

class Sparse:
    def __init__(self, n=None, *matrix):
        self.rare_values = dict()
        self.n = n
        for line in matrix:
            value, *indices = line
            c,r = sorted(indices)
            # Personally, here I would have instead used
            #   r,c = sorted(indices, reverse=True)
            # as (r,c) order seems more common, but it's no big deal.
            self.rare_values.setdefault(r, {})[c] = value

This produces the same structure as your __init__ method, just more clearly (IMO).

From there, squaring each of the values is as simple as iterating over the dict-of-dicts, e.g. using nested for loops iterating over .items():

    def square(self):
        for (r,row) in self.rare_values.items():
            for (c,val) in row.items():
                self.rare_values[r][c] = val ** 2

Example:

class Sparse:
    def __init__(self, n=None, *matrix):
        self.rare_values = dict()
        self.n = n
        for line in matrix:
            value, *indices = line
            c,r = sorted(indices)
            self.rare_values.setdefault(r, {})[c] = value

    def square(self):
        for (r,row) in self.rare_values.items():
            for (c,val) in row.items():
                self.rare_values[r][c] = val ** 2

s = Sparse(3, (0,0,0), (2,1,1), (4,0,2), (6,2,3), (8,0,4))
print(s.rare_values)  # {0: {0: 0}, 1: {1: 2}, 2: {0: 4}, 3: {2: 6}, 4: {0: 8}}
s.square()
print(s.rare_values)  # {0: {0: 0}, 1: {1: 4}, 2: {0: 16}, 3: {2: 36}, 4: {0: 64}}

Follow-up from comments

The following example shows how you might raise the matrix to a power (not the element-wise operation I showed above).

Note this code changes some things from your version and my original version. It accepts items in (r,c,v) order and doesn't attempt to "normalize" the indices like you do to force a triangular matrix.

If you want that behavior you'll have to edit this version to re-add that back.

class Sparse:
    def __init__(self, n=None, entries=None):
        self.matrix = dict()
        self.n = n
        for (r,c,v) in (entries or []):
            self.set(r, c, v)

    def set(self, r, c, v):
        self.matrix.setdefault(r, {})[c] = v

    def get(self, r, c):
        return self.matrix.get(r, {}).get(c, 0)

    def square_matrix(self):
        result = Sparse(self.n)
        for r in range(self.n):
            for c in range(self.n):
                val = sum(self.get(r,i) * self.get(i,c) for i in range(self.n))
                result.set(r, c, val)

        return result

sparse = Sparse(2, [
    (0,0,1), (0,1,2),
    (1,0,3), (1,1,4),
])
print(sparse.matrix)   # {0: {0: 1, 1: 2}, 1: {0: 3, 1: 4}}
#                        = [[1 2]
#                           [3 4]]
result = sparse.square_matrix()
print(result.matrix)   # {0: {0: 7, 1: 10}, 1: {0: 15, 1: 22}}
#                        = [[ 7 10]
#                           [15 20]]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文