2015-08-20 3 views
1

По просьбе Мартина здесь есть основная проблема. Существует функция M (x), которая должна быть минимизирована на интервале [lb, ub].Поиск минимума функции в интервале

M = @(x) (a_1 * x + b_1) * (log((a_1 * x + b_1)/P_1) + X_u)... 
    + (a_2 * x + b_2) * (log((a_2 * x + b_2)/P_2) + X_m)... 
    + x * (log(x/P_3) + X_d); 
lb = max(0, -b_1/a_1); 
ub = -b_2/a_2; 

где входы:

P_1 = 0.6; 
P_2 = 0.2; 
P_3 = 0.2; 
a_1 = 0.7071; 
a_2 = -1.7071; 
b_1 = 0.0245; 
b_2 = 0.9755; 
X_u = 44; 
X_m = 2.9949; 
X_d = 0; 

Другим вариантом было бы решить за корень уравнения m_dash:

m_dash = @(x) log(((a_1 .* x + b_1).^a_1) .* ((a_2 .* x + b_2).^a_2) .* x)... 
    - log((P_1.^a_1) .* (P_2.^a_2) .* P_3) + a_1 .* X_u + a_2 .* X_m + X_d; 

Любая помощь будет высоко оценили.

+0

Это много кода для поиска нуля ... Есть ли способ уменьшить количество кода, чтобы явно показать проблему? –

+0

Уважаемый Мартин, общая проблема заключается в минимизации функции M: '@ (x) (a_1 * x + b_1) * (ln ((a_1 * x + b_1)/P_1) + X_u) ... + (a_2 * x + b_2) * (ln ((a_2 * x + b_2)/P_2) + X_m) ... + x * (ln (x/P_3) + X_d); где вариант нахождения нулевого М 'казался мне наиболее логичным, в первую очередь, поскольку уникальность решения уже доказана. Но найти этот конкретный ноль с помощью M 'оказалось намного сложнее, чем я думал изначально. –

+1

Благодарим за редактирование! В качестве подсказки вы, скорее всего, получите ответы, когда вы выбросите другой код и уменьшите свой вопрос до минимального рабочего примера MWE. (Вам нужно будет определить 'M',' a_1', 'a_2', ... для вашей проблемы быть хорошим MWE.) Многие люди в stackoverflow не читают вопросы, в которых есть много кода. –

ответ

2

Если вы хотите свести к минимуму функцию за определенный интервал, вы можете использовать функцию fminbnd из Оптимизационной панели инструментов. Если вы не установили, что набор инструментов, вы можете попробовать free alternative, или вместо того, чтобы принуждать встроенную функцию fminsearch только возвращать результаты из интервала:

rlv = 1e12; % ridiculously large value 
M_hacked= @(x) rlv*((x < lb) + (x > ub)) + M(x); 
x_min = fminsearch(M_hacked, (lb + ub)/2) 

я представил новую функцию, M_hacked, которая возвращает смехотворно большие значения для x вне интервала.

Это не самое элегантное решение, но оно должно сделать для вашей проблемы.

+0

Я просто попробовал ваш ответ, и его ответ на 0.0006 точнее, чем fminbnd. Хотя оба работают. Большое спасибо! –