2x2矩阵中元素的所有组合,行和列总和等于指定值

时间:2016-11-05 16:32:05

标签: python c r matrix combinations

背景

我正在尝试编码Fisher的精确测试(参见:wiki),特别是2 x 2列联表(矩阵)。但是我坚持在一个特定的步骤: 在给定观察到的非负整数矩阵的情况下生成替代矩阵,其中替代矩阵的行和列总和必须等于原始矩阵。 / em> This page (Wolphram)描述了所有步骤,但下面我会详细说明我坚持使用的位。

问题

为了对2 x 2列联表实施Fisher精确检验,给出了一个2 x 2矩阵,其元素是表示观测值的非负整数,观察到的矩阵。

其中一个步骤要求我生成2 x 2矩阵的所有组合,替代矩阵,其非负整数元素受以下条件限制:

  • 所有替代矩阵的尺寸为2 x 2,即等于观察到的矩阵。
  • 替代矩阵的每一行的总和必须等于观察到的矩阵的每一行的相应总和,即在每个替代矩阵中观察到的矩阵的行2的总和=行的总和。 / LI>
  • 替代矩阵的每列的总和必须等于观察到的矩阵的每列的对应总和。

对我而言,生成替代矩阵的最明显方法是在2 x 2矩阵中强制所有可能的数字组合,其值小于或等于观察到的矩阵的行/列的总和。然后迭代这些组合,过滤掉不符合上述条件的组合。

编辑:在2x2矩阵(替代矩阵)中生成所有元素组合的最快算法是什么,行和列总和等于观察到的 / em>矩阵?

原文:我们如何用以下任何一种语言实现它:R,Python,C / C ++,Matlab?

示例

对于2×2测试的示例应用,让X成为期刊,比如数学杂志或科学,并且让Y成为关于数学和生物学主题的文章的数量出现在其中一个这些期刊。如果“数学杂志”有五篇关于数学的文章和一篇关于生物学的文章,而“科学”没有关于数学和关于生物学的四篇文章,那么相关的矩阵将是:

enter image description here

然后所有可能的替代矩阵将是:

enter image description herew

相关帖子

2 个答案:

答案 0 :(得分:1)

我有一个使用sympy的答案。这个想法是一样的:解决从矩阵元素之和得到的线性方程组,即行数和列数。这是硬编码的M. s基本上是你的矩阵。 linsolve为您提供了无限的解决方案,其余的将它们限制为正整数。

from sympy import *
from sympy.solvers.solveset import linsolve
from sympy.sets.fancysets import Naturals0
from sympy.solvers.inequalities import reduce_inequalities

M = Matrix([[1,1,0,0],[0,0,1,1],[1,0,1,0],[0,1,0,1]])
s = Matrix([5,5,6,4])

a,b,c,d = symbols('a, b, c, d')
solution = linsolve((M,s), [a,b,c,d])

solution_eq = [x >= 0 for x in list(list(solution)[0])]
possible_values = reduce_inequalities(solution_eq, x.free_symbols)

for d_fixed in Intersection(possible_values.as_set(), Naturals0()):
    print solution.subs({d : d_fixed})

答案 1 :(得分:0)

这实际上非常简单。您只需要选择符合条件的所有可能组合。

这是python中的解决方案:

# [[i, j]
#  [k, l]]

def findAlternativeMatrices(c):
    # arg c = cont. matrix
    # this only works for integers
    alt = []
    # no single value inside an alternative matrix
    # can be bigger than the largest row/column-sum 
    N = max([c[0][0]+c[1][0],c[0][1]+c[1][1],c[0][0]+c[0][1], c[1][0]+c[1][1]])
    # loop over all matrix entries
    for i in range(N):
        for j in range(N):
            for k in range(N):
                for l in range(N):
                    #check if the respective sums equal
                    if(     (i+k == (c[0][0]+c[1][0]) )
                        and (j+l == (c[0][1]+c[1][1]) )
                        and (i+j == (c[0][0]+c[0][1]) )
                        and (k+l == (c[1][0]+c[1][1]) ) ):

                        if [[i,j],[k,l]] != c:
                            # append the matrix 
                            # if it isn't the given cont. matrix
                            alt.append([[i,j],[k,l]])

    return alt


c = [[5,0],[1,4]]
alt = findAlternativeMatrices(c)

for a in alt:
    print a