Условный минимум 4D матрицы: найти минимизирующие векторы

#python #numpy #linear-algebra #minimization

#python #numpy #линейная алгебра #минимизация

Вопрос:

Я предполагаю, как условно минимизировать матрицу 4D.

Давайте начнем создавать некоторые игрушечные данные (которые близки к моей реальной проблеме):

 import numpy as np

t = np.arange(1960,1981,1)
N = np.arange(0,3,1)

k = np.arange(0,5,0.1)
k_matrix = ( np.tile(k,(len(N),1)).T * (N 1)/(N 2) ).T

p = np.arange(0.1,2.01,0.1)

theory = np.random.normal(10,1,[len(N),len(t),len(p)])

res2 = np.zeros([len(N),len(t),len(k),len(p)])

def calc_res2(N,t,k_matrix,p,theory):
    for N_ind, N_val in enumerate(N):
        for t_ind, t_val in enumerate(t):
            for k_ind, k_val in enumerate(k_matrix[N_ind]):
                for p_ind, p_val in enumerate(p):
                    res2[N_ind,t_ind,k_ind,p_ind] = (N_val*t_val-k_val*theory[N_ind,t_ind,p_ind])**2

    return res2

test = calc_res2(N,t,k_matrix,p,theory)
 

Я хочу найти такие индексы / значения k_matrix (как функция N ) и p (как функция t ), которые
test суммируются t и N будут минимальными.

Теперь я вижу, что эту проблему можно решить с помощью for циклов:

 def k_multi_N (test,k_matrix,p):
    SUM_best = 1e99
    k0i_b,k1i_b,k2i_b = 0,0,0
    for k0_ind,k0 in enumerate(k_matrix[0]):
        temp = test[0,:,k0_ind,:] 
        for k1_ind,k1 in enumerate(k_matrix[1]):
            temp  = test[1,:,k1_ind,:] 
            for k2_ind,k2 in enumerate(k_matrix[2]):
                temp  = test[2,:,k2_ind,:] 

                SUM = sum(temp.min(axis=1))
                if SUM < SUM_best:
                    SUM_best = SUM
                    p_min_ind = np.argmin(temp,axis=1)
                    k0i_b,k1i_b,k2i_b = k0_ind,k1_ind,k2_ind

                temp -= test[2,:,k2_ind,:]
            temp -= test[1,:,k1_ind,:] 
        temp -= test[0,:,k0_ind,:]  

    return p_min_ind, (k0i_b,k1i_b,k2i_b)

k_multi_N (test,k_matrix,p)
 

Таким образом, ожидаемый результат:

 (array([12, 16, 14,  8, 14, 18,  1, 18,  9,  9, 15, 18,  9, 13,  9,  3,  3,
        18, 13,  6, 19]),
 (0, 49, 49))
 

но вычислительная эффективность будет очень мала, учитывая векторы большого размера N и k (мой реальный случай — 16 * 200 для N*k 800 * 200 для ‘t * k`, так что это будет 16 ^ 200 итераций с матрицами 800 * 200 : (

Конечно, я рассматривал numba решение, но оно не позволяет мне значительно ускорить вычисления (т. Е. Это все еще занимает много времени!).

Мне интересно узнать об альтернативных, более эффективных с точки зрения вычислений способах решения проблемы. Спасибо!

РЕДАКТИРОВАТЬ: вопрос был существенно изменен, чтобы прояснить проблему. Я ценю людей, которые помогли мне это сделать!

Комментарии:

1. t , p , N и k — все константы в вашем коде. Поэтому я не понимаю, что означают точки 1 и 2.

2. Я попытался уточнить формулировку, надеюсь, теперь она выглядит более удобной.

3. Возможно, чтобы прояснить ваши намерения, попробуйте еще более простую настройку и предоставить ожидаемый результат. Например: t,N,p,k = 2,3,4,5; test = np.arange(t*N*p*k).reshape([t,N,p,k])

4. Формулировка ‘argmin’ здесь сбивает с толку, и я не понимаю, как размеры v1 и v2 будут такими, как вы говорите