Стохастическая матрица Python

Я пытаюсь создать функцию, которая проверяет, являются ли матрица и вектор стохастическими (сумма элементов = 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')

person AntonYellow    schedule 06.08.2020    source источник


Ответы (2)


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)

person Nathan e    schedule 06.08.2020
comment
sum(row) == 1 for row in M.T является выражением генератора и не возвращает список - person user8408080; 06.08.2020
comment
Большое спасибо. Это требует немного гимнастики с логическими переменными, на которых я не обучен :-) Я постараюсь усвоить больше упражнений. - person AntonYellow; 06.08.2020

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

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

  2. Логическая ошибка на шаге b[None,:]=is_sto(column). Это устанавливает ОБЕ значения от 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]])
person Akshay Sehgal    schedule 06.08.2020
comment
Большое спасибо за ваш совет, этот код чист и ясен для понимания. Мне нужно больше упражнений, чтобы организовать свое кодовое мышление таким образом. Теперь течет лучше. - person AntonYellow; 07.08.2020
comment
Рад помочь. Продолжайте работать над этим, и это станет вашей второй натурой в кратчайшие сроки :) - person Akshay Sehgal; 07.08.2020