Python сточасти c матрица - PullRequest
       71

Python сточасти c матрица

0 голосов
/ 06 августа 2020

Я пытаюсь создать функцию, которая проверяет, являются ли матрица и вектор сточасти c (сумма элементов = 1 для всех столбцов как матрицы, так и, конечно, вектора), если да, она применяет матричное произведение между M и p в противном случае возникает ошибка. Я создал функцию под названием is_sto , чтобы проверить сумму = 1 для векторов. Я пробовал что-то, что не работает ... Я немного скептически отношусь к тройному И , но я не смог сделать лучше. Можно ли получить подсказку? Большое спасибо

p=np.array([[0.5],[0.5]])
M=np.array([[0.3,0.5], [0.7,0.5]])
b=np.zeros(2)

def matrix_stoch (p,M):
   
 for column in M.T:
   
   b[None,:]=is_sto(column)
    
v= (b[0] and b[1] and is_sto(p))

if v == True:
       np.dot(M,p)
else:
      raise ValueError('no stochastic matrix')

Ответы [ 2 ]

0 голосов
/ 06 августа 2020

Есть несколько проблем с функцией, которую вы написали -

  1. Отступ в вашем коде неправильный, и он помещает код после v вне функции (Я надеюсь, что вы только что допустили ошибку копирования и вставки в Stackoverflow). Это делает вектор b всегда равным [0,0], потому что операции, которые вы выполняете внутри функций, имеют другую область видимости, поскольку они являются локальными переменными функции. Таким образом, это всегда возвращает ValueError

  2. На шаге b[None,:]=is_sto(column) есть ошибка logi c. Это устанавливает ОБЕ значения от b[0] and b[1] до [1,1] для КАЖДОЙ КОЛОНКИ из M.T. Я очень сомневаюсь, что вы пытаетесь это сделать, поскольку в этом нет смысла. Я считаю, что вы хотите получить b[0] = 1 для первого столбца и b[1] = 1 для второго столбца.

  3. В вашем коде нет return для no.dot.

Я бы порекомендовал использовать следующий код, который значительно упрощает всю проблему и избавляет от ошибок. Это также исключает вектор b из изображения и, следовательно, ошибочную логическую индексацию.

p=np.array([[0.5],[0.5]])
M=np.array([[0.3,0.5], [0.7,0.5]])

def is_sto(arr):
    return np.sum(arr)==1

def matrix_stoch(p,M):
    M_sto = [is_sto(i) for i in M.T]
    p_sto = is_sto(p)

    print('Stochastic check on columns of M: ', M_sto)
    print('Stochastic check on vector p: ', p_sto)

    if all(M_sto) and p_sto:
        return np.dot(M,p)
    else:
        raise ValueError('no stochastic matrix')

matrix_stoch(p,M)
Stochastic check on columns of M:  [True, True]
Stochastic check on vector p:  True

array([[0.4],
       [0.6]])
0 голосов
/ 06 августа 2020

v эквивалентно:

all(sum(row) == 1 for row in M.T) and sum(float(elt) for elt in p) == 1

sum(row)==1 for row in M.T возвращает список длины вашего числа столбцов, с элементом True в позиции i, если сумма i-го столбца равна единице.

all - это встроенная функция python, которая проверяет, все ли элементы списка истинны. Если это так, он возвращает True. Здесь он возвращает True тогда и только тогда, когда все ваши столбцы имеют сумму 1.

Кроме того, вы проверяете if v == True:. Вы можете просто написать if v:, это проще;)

def matrix_sto(p,M):
    if all(sum(row) == 1 for row in M.T) and sum(float(elt) for elt in p) == 1:
        np.dot(M,p)
    else:
        raise ValueError('no stochastic matrix')

если вы хотите более простое решение, вы могли бы написать:

import numpy as np

def matrix_sto(p,M):
    bool = True
    for row in M.T:
        bool = bool and sum(row) == 1
    
    sum_vector=0
    for elt in p:
        sum_vector += float(elt)
    bool = bool and sum_vector == 1
    if bool:
        np.dot(M,p)
    else:
        raise ValueError('no stochastic matrix')

Более того, я думаю, вам нужно поместите где-нибудь возврат;)

Если вы хотите получить результат np.dot(M,p), измените его на return np.dot(M,p)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...