Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 多处理直接计算_Python_Multithreading_Numpy_Multiprocessing_Sage - Fatal编程技术网

Python 多处理直接计算

Python 多处理直接计算,python,multithreading,numpy,multiprocessing,sage,Python,Multithreading,Numpy,Multiprocessing,Sage,问题分解:有相当多的潜在动机,但假设我们得到了一些矩阵N(代码包含在底部),我们希望解决矩阵向量方程Nv=b,其中b是一个权重为k的二进制字符串。我目前正在使用numpy.linalg.lstsq解决这个问题。如果这个最小二乘计算的“残差”小于0.000001,我接受它作为解决方案 首先,我需要生成特定长度和权重k的所有二进制字符串。下面的函数可以实现这一点 ''' This was provided in one of the answers here: https://stackoverf

问题分解:有相当多的潜在动机,但假设我们得到了一些矩阵
N
(代码包含在底部),我们希望解决矩阵向量方程
Nv=b
,其中
b
是一个权重为
k
的二进制字符串。我目前正在使用
numpy.linalg.lstsq
解决这个问题。如果这个最小二乘计算的“残差”小于0.000001,我接受它作为解决方案

首先,我需要生成特定
长度
权重k
的所有二进制字符串。下面的函数可以实现这一点

'''
This was provided in one of the answers here: 
https://stackoverflow.com/questions/58069431/find-all-binary-strings-of-certain-weight-has-fast-as-possible/
Given a value with weight k, you can get the (co)lexically next value as follows (using bit manipulations).
'''
def ksubsetcolexsuccessor(length,k):
    limit=1<<length
    val=(1<<k)-1
    while val<limit:
        yield "{0:0{1}b}".format(val,length)
        minbit=val&-val
        fillbit = (val+minbit)&~int(val)
        val = val+minbit | (fillbit//(minbit<<1))-1
我们将每个都插入
Nv=b
并求解:

import numpy as np

solutions = 0
for b in ksubsetcolexsuccessor(n, k):
    v = np.linalg.lstsq(N,np.array(list(b), dtype = float)) 
    if v[1] < 0.000001:
        solutions += 1
这确实减少了大约45%的计算时间(随着长度和重量的增加)。在此期间,我的CPU大约以50%的速度运行。奇怪的是,如果我分为4个进程,所需的时间与分为2个进程所需的时间大致相同(尽管在此期间我的CPU运行率约为85%)。在我正在测试的笔记本电脑上,我有2个物理核和4个逻辑核。在这样一个CPU上,有多少个进程是最佳的

问题:

  • 在我缺乏多处理知识的情况下,我是否正确地做到了这一点?i、 这是多处理这个程序的最快方法吗
  • 有人能找到任何提高计算时间的清晰方法吗?我已经研究了每个进程中的多线程,但它似乎减慢了计算速度
  • 最慢的部分肯定是
    np.linalg.lsts
    q。有什么聪明的方法来加速这部分吗
  • 如果有人想测试代码,下面是我如何生成矩阵
    N

    '''
    Creating the matrix N
    '''
    def matrixgenerator(G, cardinality, degree):
        matrix = np.zeros((size, (n-1)**2 + 1))
        #Generate the matrix (it'll be missing stab_nn)
        column_index = 0
        for i in range(1,n):
            for j in range(1,n):
                for k in range(size):
                    if G[k](i) == j:
                        matrix[k][column_index] = 1
                column_index += 1
    
        #Determine the final column of N, which is determined by the characteristic vector of stab_nn
        for k in range(size):
            if G[k](n) == n:
                matrix[k][(n-1)**2] = 1
    
        return matrix
    
    n = 3 #This will give length 6 and weight 2 binary strings
    #Try n = 7 and change the second argument below to '4' - this takes roughly 14 min with 2 processes on my device
    Group = TransitiveGroup(n, 2) #SageMath 8.8
    length = Group.order()
    weight = int(size / n)
    
    N = matrixgenerator(Group, length, n)
    

    这需要SageMath 8.8。注意,这是代码中唯一需要SageMath的部分。其他所有内容都有效地用Python 2.7编写。提前感谢。

    讲讲性能-在所有尽可能快的方法中,(预期的)最快方法的可接受水平是多少?没有量化的目标,任何一条道路都可能引领一个人前进。我想如果你看到任何可以改进的地方,如果你能解释一下这是什么,那就太好了,我会做出改变。我的量化目标是,我不希望n=168和k=21需要6个月的时间来计算,如果我对线性代数的微弱记忆是正确的,那么你就不必解那么多方程了。只需求解标准基,e1,e2,e3,。。。返回项目以获取ehat1、ehat2、ehat3,。。。现在查找满足e_j1+e_j2+e_j3+的所需大小的组j1、j2、j3(二进制字中的位置)。。。约ehat_j1+ehat_j2+ehat_j3+。。。您应该能够一次获得所有EHAT,作为
    N@np.linalg.pinv(N) 
    但是无论你优化得多么好,循环遍历所有168-choose-21(~2.9 x 10^26)字都是不可行的。矩阵N实际上已经是基向量的集合,但我会仔细考虑你所说的。也许我有点热心。那么n=72和k=8呢?
    from multiprocessing import Process
    
    '''
    A version where you can specify where to start and end by passing start_val and end_val to the function.
    It performs the least-squares computation for each b and tallies the trials that work.
    '''
    def ksubsetcolexsuccessorSegmentComp(n, k, val, limit, num):
        while val<limit:
            b = "{0:0{1}b}".format(val,n)
            v = np.linalg.lstsq(N,np.array(list(b), dtype = float))
            if v[1] < 0.000001:
                num += 1
    
            minbit=val&-val
            fillbit = (val+minbit)&~int(val)
            val = val+minbit | (fillbit//(minbit<<1))-1
    
        print(num)
    
    
    solutions = 0
    length = 6
    weight = 2
    start_val = (1<<k)-1
    mid_val = 18 #If splitting into 2 processes
    end_val = 1<<n
    
    #Multiprocessing
    p1 = Process(target=ksubsetcolexsuccessorSegmentComp, args=(length, weight, start_val, mid_val, solutions))
    p2 = Process(target=ksubsetcolexsuccessorSegmentComp, args=(length, weight, mid_val, end_val, solutions))
    
    p1.start()
    p2.start()
    
    p1.join()
    p2.join()
    
    '''
    Creating the matrix N
    '''
    def matrixgenerator(G, cardinality, degree):
        matrix = np.zeros((size, (n-1)**2 + 1))
        #Generate the matrix (it'll be missing stab_nn)
        column_index = 0
        for i in range(1,n):
            for j in range(1,n):
                for k in range(size):
                    if G[k](i) == j:
                        matrix[k][column_index] = 1
                column_index += 1
    
        #Determine the final column of N, which is determined by the characteristic vector of stab_nn
        for k in range(size):
            if G[k](n) == n:
                matrix[k][(n-1)**2] = 1
    
        return matrix
    
    n = 3 #This will give length 6 and weight 2 binary strings
    #Try n = 7 and change the second argument below to '4' - this takes roughly 14 min with 2 processes on my device
    Group = TransitiveGroup(n, 2) #SageMath 8.8
    length = Group.order()
    weight = int(size / n)
    
    N = matrixgenerator(Group, length, n)