рекурсия для n-мерной матрицы - PullRequest
2 голосов
/ 02 июля 2019

Я делаю некоторую реализацию в Python 3, и мне нужна помощь.У меня есть функция, которая зависит от размерности матриц.Я на самом деле имею две матрицы и хочу каким-то образом получить третью.Например (2-мерные матрицы):

def my_matrix_2d(mat1, mat2):
    ar = []
    for i in range(len(mat1[0])):
        ar1 = []
        for j in range(len(mat1[1])):
            try:
                ar1.append([mat1[0][i], mat1[1][j], mat2[i][j]])
            except IndexError:
                ar1.append([mat1[0][i], mat1[1][j], None])
        ar.append(ar1)
    return ar

Другой пример для 3-мерных матриц:

def my_matrix_3d(mat1, mat2):
    ar = []
    for i in range(len(mat1[0])):
        ar1 = []
        for j in range(len(mat1[1])):
            ar2 = []
            for k in range(len(mat1[2])):
                try:
                    ar2.append([mat1[0][i], mat1[1][j], mat1[2][k], mat2[i][j][k]])
                except IndexError:
                    ar2.append([mat1[0][i], mat1[1][j], mat1[2][k], None])
            ar1.append(ar2)
        ar.append(ar1)
    return ar

Мне нужно сделать общую функцию для n-мерных матриц.Я знаю, что это должно быть что-то с рекурсией, но я просто не могу понять это.Я был бы признателен за любую помощь.

РЕДАКТИРОВАТЬ:

Я на самом деле не очень хорошо описал мою проблему, поэтому я постараюсь дать подробное описание.Во-первых, я опишу 2D проблему.У меня есть две матрицы, mat1 и mat2.len (mat1) = 2, и скажем, что len (mat1 [0]) = m и len (mat1 [1]) = n.Тогда mat2 - это матрица mxn, поэтому len (mat2) = m и len (mat2 [i]) = n для i = 0,1, ..., m-1.my_matrix_2d - это функция, которая каким-то образом объединяет эти две матрицы.Давайте рассмотрим конкретный пример: мы можем видеть mat1 как ребра бинов 2D-гистограммы и mat2 как высоты бинов, поэтому mat1 [0] представляет ребра бинов в x-координате, а mat1 [1] представляет ребра бинов в y-координате.mat2 представляет высоты бинов на пересечении ребра с координатами x и y.Таким образом, my_matrix_2d хранит информацию о ребрах и высоте бинов в 2-мерной гистограмме.Его элементами являются векторы (mat1 [0] [i], mat1 [1] [j], mat2 [i] [j]), и поскольку нам требуется еще одно ребро для определения ширины бинов, последними векторами являются (mat1 [0] [i], mat1 [1] [j], нет).

Аналогично в 3D-примере.mat1 [0] (len = m) - ребра бинов в x-координате, mat1 [1] (len = n) - ребра бинов в y-координате, mat1 [2] (len = o) - ребра бинов в z-координате, а mat2 - матрица mxnxo, которая содержит высоты бинов.Вывод my_matrix_3d должен представлять собой матрицу / массив с элементами (mat1 [0] [i], mat1 [1] [j], mat1 [2] [k], mat2 [i] [j] [k]), где i =0, ..., m-2, j = 0, ..., n-2, k = 0, ..., o-2, и если i = m-1 или j = n-1 или k =o-1, элемент в матрице должен быть (mat1 [0] [i], mat1 [1] [j], mat1 [2] [k], None).

PS my_matrix_nd должен быть n-мерным)матрица, которая имеет ту же форму, что и mat2.Но элементы в mat2 являются числами с плавающей точкой, а элементы в my_matrix_nd - это векторы len (mat1) +1.

EDIT2:

Я поставил конкретный пример (2D):

mat1 = [
array([-82.8894492, -56.07043142, -29.25141365, -2.43239587, 24.3866219,  51.20563967,  78.02465745]),
array([-191.15188724, -103.20853717, -15.2651871, 72.67816297, 160.62151304, 248.56486311])
]

mat2 = array([[4.23988548e-08, 3.39190838e-07, 1.27196564e-07, 1.27196564e-07, 0.00000000e+00],
[1.22956679e-06, 8.35257440e-06, 1.53483854e-05, 4.45187976e-06,
1.69595419e-07],
[5.00306487e-06, 4.77835094e-05, 8.47553108e-05, 2.31073759e-05,
1.05997137e-06],
[5.13026143e-06, 5.80016334e-05, 9.37862668e-05, 2.62872900e-05,
1.01757252e-06],
[1.14476908e-06, 1.44156106e-05, 2.33617690e-05, 6.52942364e-06,
2.54393129e-07],
[0.00000000e+00, 5.93583967e-07, 1.10237023e-06, 4.23988548e-07,
4.23988548e-08]])

output:
[

[[-82.88944919513716, -191.1518872423128, 4.2398854812237576e-08], 
[-82.88944919513716, -103.20853717269506, 3.391908384979006e-07], 
[-82.88944919513716, -15.265187103077324, 1.2719656443671272e-07], 
[-82.88944919513716, 72.67816296654041, 1.2719656443671272e-07], 
[-82.88944919513716, 160.62151303615815, 0.0],
[-82.88944919513716, 248.56486310577586, None]],

[[-56.07043142169904, -191.1518872423128, 1.2295667895548898e-06], 
[-56.07043142169904, -103.20853717269506, 8.352574398010803e-06], 
[-56.07043142169904, -15.265187103077324, 1.534838544203e-05], 
[-56.07043142169904, 72.67816296654041, 4.451879755284945e-06], 
[-56.07043142169904, 160.62151303615815, 1.6959541924895036e-07], 
[-56.07043142169904, 248.56486310577586, None]],

[[-29.25141364826092, -191.1518872423128, 5.003064867844034e-06], 
[-29.25141364826092, -103.20853717269506, 4.7783509373391746e-05], 
[-29.25141364826092, -15.265187103077324, 8.475531076966292e-05], 
[-29.25141364826092, 72.67816296654041, 2.3107375872669477e-05], 
[-29.25141364826092, 160.62151303615815, 1.0599713703059398e-06], 
[-29.25141364826092, 248.56486310577586, None]],

[[-2.4323958748228023, -191.1518872423128, 5.130261432280746e-06], 
[-2.4323958748228023, -103.20853717269506, 5.8001633383141e-05], 
[-2.4323958748228023, -15.265187103077324, 9.378626684466952e-05], 
[-2.4323958748228023, 72.67816296654041, 2.628728998358729e-05], 
[-2.4323958748228023, 160.62151303615815, 1.0175725154937022e-06], 
[-2.4323958748228023, 248.56486310577586,None]],

[[24.386621898615317, -191.1518872423128, 1.144769079930414e-06], 
[24.386621898615317, -103.20853717269506, 1.4415610636160767e-05], 
[24.386621898615317, -15.265187103077324, 2.336176900154289e-05], 
[24.386621898615317, 72.67816296654041, 6.529423641084582e-06], 
[24.386621898615317, 160.62151303615815, 2.543931288734254e-07], 
[24.386621898615317, 248.56486310577586, None]],

[[51.20563967205345, -191.1518872423128, 0.0],
[51.20563967205345, -103.20853717269506, 5.935839673713263e-07], 
[51.20563967205345, -15.265187103077324, 1.1023702251181777e-06],
[51.20563967205345, 72.67816296654041, 4.2398854812237604e-07], 
[51.20563967205345, 160.62151303615815, 4.2398854812237616e-08], 
[51.20563967205345, 248.56486310577586, None]],

[[78.02465744549156, -191.1518872423128, None],
[78.02465744549156, -103.20853717269506, None],
[78.02465744549156, -15.265187103077324, None],
[78.02465744549156, 72.67816296654041, None],
[78.02465744549156, 160.62151303615815, None],
[78.02465744549156, 248.56486310577586, None]]

]

1 Ответ

0 голосов
/ 03 июля 2019

Рекурсия не слишком сложна:

def lookup(m,ii):
  try:
    for i in ii: m=m[i]
  except IndexError: m=None
  return m
def edge_product(mat1,mat2,path=[]):
  return [edge_product(mat1,mat2,path+[i])\
          for i in range(len(mat1[len(path)]))]\
    if len(path)<len(mat1) else\
    [mat1[i] for i in path]+[lookup(mat2,path)]

Обратите внимание, что изменяемый аргумент по умолчанию здесь не является ошибкой: он никогда не мутирует.

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