np.block не может объединить массив (1,2) с массивом (1,1) в одной строке - PullRequest
0 голосов
/ 04 марта 2020

Таким образом, в основном с помощью приведенного ниже кода я пытался выполнить некоторую «декомпозицию lu с рамками», как в моей домашней работе. Руководство numpy .block в основном говорит, что мы можем создать блочную матрицу с np.block, если вдоль одной оси у нас есть массивы одинакового размера.

Я так понимаю: если у вас есть A с формой (2,2) b с формой (2,1) c с формой (1,2) d с формой (1,1) тогда вы можете go np.block([[A,b],[c,d]]), что даст вам квадратную матрицу размером 3by3. Но дело в том, что это не работает, когда я делаю граничное разложение lu с моей случайной матрицей 3by3, сообщение об ошибке выглядит следующим образом:


   ---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-49-175793d9912d> in <module>()
     49 L,U = bordered_lu(A[:2,:2], np.array([A[0][0]]).reshape(1,1), np.array([1]).reshape(1,1))
     50 print(L,U)
---> 51 L_dash,U_dash = bordered_lu(A,L,U)
     52 
     53 

<ipython-input-49-175793d9912d> in bordered_lu(A, tilde_ell, tilde_u)
     36     U = np.block([   
     37     [tilde_u,  e ],
---> 38     [np.zeros((1, A.shape[1] - 1)), np.array([tau]).reshape(1,1)]
     39     ])
     40 

<__array_function__ internals> in block(*args, **kwargs)

~/anaconda3_420/lib/python3.5/site-packages/numpy/core/shape_base.py in block(arrays)
    852         return _block_slicing(arrays, list_ndim, result_ndim)
    853     else:
--> 854         return _block_concatenate(arrays, list_ndim, result_ndim)
    855 
    856 

~/anaconda3_420/lib/python3.5/site-packages/numpy/core/shape_base.py in _block_concatenate(arrays, list_ndim, result_ndim)
    896 
    897 def _block_concatenate(arrays, list_ndim, result_ndim):
--> 898     result = _block(arrays, list_ndim, result_ndim)
    899     if list_ndim == 0:
    900         # Catch an edge case where _block returns a view because

~/anaconda3_420/lib/python3.5/site-packages/numpy/core/shape_base.py in _block(arrays, max_depth, result_ndim, depth)
    664     if depth < max_depth:
    665         arrs = [_block(arr, max_depth, result_ndim, depth+1)
--> 666                 for arr in arrays]
    667         return _concatenate(arrs, axis=-(max_depth-depth))
    668     else:

~/anaconda3_420/lib/python3.5/site-packages/numpy/core/shape_base.py in <listcomp>(.0)
    664     if depth < max_depth:
    665         arrs = [_block(arr, max_depth, result_ndim, depth+1)
--> 666                 for arr in arrays]
    667         return _concatenate(arrs, axis=-(max_depth-depth))
    668     else:

~/anaconda3_420/lib/python3.5/site-packages/numpy/core/shape_base.py in _block(arrays, max_depth, result_ndim, depth)
    665         arrs = [_block(arr, max_depth, result_ndim, depth+1)
    666                 for arr in arrays]
--> 667         return _concatenate(arrs, axis=-(max_depth-depth))
    668     else:
    669         # We've 'bottomed out' - arrays is either a scalar or an array

ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 0, the array at index 0 has size 2 and the array at index 1 has size 1 

мой код выглядит следующим образом:

import numpy as np
from scipy.linalg import inv


def bordered_lu(A, tilde_ell, tilde_u):
"""Implementation of a bordered LU decomposition."""

    if A.shape[0] != A.shape[1]:
       raise ValueError("Square Matrix expected to have LU decomposition")

    c = A[ : A.shape[1] - 1 , - 1]
    b = A[ - 1 , : A.shape[0] - 1]
    tau = A[A.shape[0] - 1 ][A.shape[1] - 1]


    print(tau)

    d = np.array( np.matmul(inv(tilde_ell), c) )
    e = np.array( np.matmul(b, inv(tilde_u)) )                                    



    L = np.block([   
    [tilde_ell, np.zeros((A.shape[0]-1, 1)) ],
    [d, np.array([1]).reshape(1,1)]    
    ])

    print(np.zeros((1, A.shape[1] - 1)).shape)
    print(np.array([tau]).reshape(1,1).shape)
    print(A.shape[1])
    U = np.block([   
    [tilde_u,  e ],
    [np.zeros((1, A.shape[1] - 1)), np.array([tau]).reshape(1,1)]    
    ])

return L, U


n = 3
rand = np.random.RandomState(0)

A = np.array(rand.randn(n, n))

L,U = bordered_lu(A[:2,:2], np.array([A[0][0]]).reshape(1,1), np.array([1]).reshape(1,1))
L_dash,U_dash = bordered_lu(A,L,U)

Извините, это мой первый пост, я не очень уверен, как правильно отформатировать мой вопрос.

1 Ответ

0 голосов
/ 04 марта 2020

Ваши рассуждения о block верны

In [23]: np.block([[np.zeros((2,2)),np.ones((2,1))],[np.ones((1,2)),np.zeros((1,1))]])         
Out[23]: 
array([[0., 0., 1.],
       [0., 0., 1.],
       [1., 1., 0.]])

Но давайте рассмотрим эту ошибку более подробно

ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 0, the array at index 0 has size 2 and the array at index 1 has size 1 

Если я изменю (1,2) на ( 2,2), я получаю вашу ошибку

In [24]: np.block([[np.zeros((2,2)),np.ones((2,1))],[np.ones((2,2)),np.zeros((1,1))]]) 
....
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 0, the array at index 0 has size 2 and the array at index 1 has size 1

Другими словами, a (2,2) с (1,1) создает проблему.

Так что вам нужно проверить формы всех элементов переданы в block. Я еще не проверил ваши логи c достаточно подробно.

...