Собираюсь учитывать, пока рассматриваю простейший случай. Нужно отработать алгоритм.
Ну, это не верный подход. Та задача, которую вы сейчас поставили очень хорошая: целевая функция выпукла (если не ошибаюсь) на множестве определения и задана так же на выпуклом множестве. В таком хорошем случае минимум существует и единственен. То есть если программа находит какой-то локальный минимум (с учётом ограничений), то это будет как раз тот самый, который нужен. Если же добавить нелинейное ограничение
(кстати, чему равна эта константа, если
-- количество вещества в молях?), то даже выпуклая функция может иметь несколько локальных минимумов. В этом случае программа должна найти их все и выбрать наименьший, а это весьма сложная задача.
Также интересует, за сколько времени рассчитывается полученное вами решение.
Время вычислений с точностью до
(максимальная возможная точность) доли секунды и это учитывая то, что программа на матлабе (в том числе и функция многомерной оптимизации) -- это скрипт, а не код. Для достижения указанной точности при указанных вами значениях констант и связей целевая функция вычислялась 1060 раз.
Использовать вашу подстановку
или мою с иррациональностью нельзя, так как в случае, когда минимум функции достигается, когда один из иксов равняется нулю, соответствующий штрихованный икс должен равняться минус бесконечности, то есть после такой подстановки целевая функция получается не имеет экстремума (он лежит на бесконечности). Этим объясняется то, что ваша программа очень долго считает: одна из координат долго уходит на бесконечность (так как делает это конечными шагами).
Чтобы избежать эту проблему, но, тем не менее, удовлетворить условиям положительности иксов, целевую функцию я определил следующим образом:
, если все
положительны
, если хотя бы один
отрицателен.
Для поиска минимума целевой функции я использовал встроенную в МАТЛАБ процедуру
fminsearch, которая использует алгоритм Нелдера — Мида многомерной оптимизации. Этот алгоритм очень удобен, но имеет свои практические недостатки. Например, все аргументы функции должны иметь один порядок. Для обхода этого недостатка, для уменьшения количества переменных, по которым будет вестись оптимизация, а так же для удовлетворения связей, наложенных на аргументы, я использовал следующую подстановку:
Чтобы получить эту подстановку я исследовал связи и ограничения (благо, что все связи линейные). Нашёл, в каких диапазонах может изменяться каждый из иксов, выбрал зависимые и независимые переменные, выразил зависимые через независимые и независимые отмасштабировал с учётом их диапазона так, чтобы они изменялись в пределах от нуля до единицы. Таким образом, я уменьшил размерность задачи, и построил "хорошую" для процедуры оптимизации функцию.
И так, код программы:
(Оффтоп)
Файл "prov3.m"Код:
clc
clear
format compact
RT=1.985877534*298.15;
G0=[
-0056690 % H2O
0000000 % H+
0004236 % H2
-0242801 % HSiO3
0003954 % O2
-0037595 % OH-
-0199190]; % SiO2
G0dRT=G0/RT;
c1=53.51;
c2=26.755;
c3=0.0001;
A=[
c1 0 0
0 c1 0
-c1 -c1 0
0 0 c3
-c2 -c2 0
0 c1 -c3
0 0 -c3];
B=[
0
0
55.51
0
c2
0
c3];
fmso=optimset('fminsearch');
fmso=optimset(fmso,'Display','iter','TolFun',1e-20,'TolX',1e-20,'MaxIter',200000,'MaxFunEvals',400000);
y=fminsearch(@(y)prov3_fnc(B+A*y,G0dRT),0.1*ones(3,1),fmso);
x=B+A*y;
G=RT*prov3_fnc(x,G0dRT);
disp('x=')
disp(x)
disp('G=')
disp(G)
Файл "prov3_fnc.m"Код:
function G=prov3_fnc(x,G0dRT)
if sum(x<0)>0
G=Inf;
else
G=sum(x.*(G0dRT+log(x/sum(x))));
end
end
-- 13.01.2014, 14:55 --Я не знаю, насколько необходимо это условие.
Это условие влияет на концентрации и, следовательно, на количества вещества ионов
и
. Эти количества вещества связаны через электронейтральность с количеством вещества ионов
, следовательно, если в растворе не будет достаточно много других заряженных ионов, то введение ограничения, связанного с ионным произведением воды, может изменить концентрацию
на порядок и более.
но там нужно попробовать комбинацию всех крайних (максимальных - минимальных) и средних значений со всеми, т.е.
Нет, это не так. Чтобы численно найти частную производную по конкретному аргументу, необходимо
немного изменить только один этот аргумент и посмотреть, как изменилась функция.
Но в вашем случае всё можно сделать аналитически. Необходимо только учитывать тот факт, что один из искомых иксов может "упираться" в ограничение, связанное его положительностью, поэтому, если такой икс (равный нулю) в решении присутствует, то выражение для каждой частной производной будет другим, в отличие от случая, когда такого икса нет.
П.С. И всё-таки, откуда взялась функция
и почему в ней иксы -- это количество вещества, а не концентрации? Это же раствор.