Эта цель НЕ является ужасно сложной. Но вы написали это, чтобы выглядеть сложным.
Прежде всего, омега - это скаляр! Зачем писать inv (омега)? Разделение на omega - лучшая идея, так как для обратной функции не потребуются накладные расходы.
Далее, tau - известный постоянный скаляр, как и Passetcovar. Зачем вычислять обратную матрицу (tau * Passetcovar) каждый раз, когда вызывается функция? Не только это, но вы вычисляете ту же самую обратную матрицу три раза в одной строке. Учитесь прекомпомировать эти вещи. Это сэкономит вам много времени и много головных болей.
В любом случае, у вас есть навязчивая идея с inv. Он называется 6 раз в одной строке, и большинство из этих вызовов являются излишними.
Позволяет переписать эту единственную строчку. Прежде всего, прекомпуте inv (Passetcovar), передавая все это в вашу цель, поэтому вам нужно делать это ТОЛЬКО один раз.
Примечания основной идентичность:
inv(k*A) = inv(A)/k
, которая справедлива для любых ненулевых скалярных к.
IP = inv(Passetcovar);
Опять же, не повторить вычисление и (Passetcovar) каждый раз, когда целевая функция называется. Вместо этого, вычислите его ONCE, прежде чем вы начнете оптимизацию.
Таким образом, вычисление становится немного проще читать:
wcalc = IP./lambda*inv(IP./tau + PMat(i,:)'*PMat(i,:)/omega)*(IP*Pi./tau + PMat(i,:)'*Q(i,:)/omega);
Edit:
Наконец мы узнаем, что Pi является вектором. Я предполагаю, что это должен быть вектор 8x1, чтобы совпадение массива соответствовало.
Мы можем сэкономить еще несколько разделов и умножить, разложив некоторые константы и вставив паренны в удобное место. Заметим, что, вычислив вектор матрицы *, умножьте FIRST, а затем умножьте на IP, мы преобразуем 8x8 * 8x8 умножить на умножение 8x8 X 8x1. Для небольших массивов, подобных этому, разница не огромна, но стоит вспомнить идею.
wcalc = IP*(inv(IP + tau*PMat(i,:)'*PMat(i,:)/omega)*(IP*Pi + PMat(i,:)'*Q(i,:)/omega*tau))/(lambda*tau^2);
Цель состоит в том, чтобы минимизировать сумму квадратов между Wcalc и WK, при условии положительной омеги. Теперь это скаляр.
Я бы предложил сначала загладить функцию, чтобы узнать что-то о ее форме и посмотреть, что может быть хорошим стартовым значением для омеги. Таким образом, обернув дескриптор функции вокруг myfun, ezplot сделает сюжет красиво, здесь для диапазона [0,100] для омеги. Выберите свою собственную верхнюю границу для омеги, если это необоснованно.
ezplot(@(omega) myfun3(wk,omega,lambda,Passetcovar,tau,PMat,i,Pi,Q),[0,100])
Таким образом, тривиальное решение заключается в использовании fminbnd, обеспечивая некоторое разумное, но достаточно большое значение для верхней грани. Хорошая вещь о fminbnd - это не нужно начинать значения. Вам нужно будет выбрать разумную верхнюю границу для омеги. Дело в том, что используйте инструмент, предназначенный для минимизации скалярной функции. Общие оптимизаторы, такие как fmincon, не нужны и требуют начального значения.
finalomega = fminbnd(@(omega) myfun3(wk,omega,lambda,Passetcovar,tau,PMat,i,Pi,Q),[0,100])
Также вы можете использовать fminsearchbnd, найденные при обмене файлами. Он может свести к минимуму функцию, подчиненную только ограничениям, связанным с нижними границами, но для fminsearchbnd потребуется начальное значение для omega.
Обычно вам нужно кое-что о функции, чтобы убедиться, что локальный минимум - это, по сути, глобальный минимум (например, функция является выпуклой). Это так? – jedwards
Что вы подразумеваете под «минимизацией f», это не скалярный правый? –
Извините, да, это скаляр @Dennis Jaheruddin. – Mary