В этом отчёте описываются возможные пути решения задачи и проблемы, возникающие при их реализации. Многие из этих проблем исчезнут при выпуске новых версий Matlab. Использовался самый «свежий» на текущий момент Matlab 6.5.1 от 4 августа 2003 года со всеми установленными пакетами.
Цель: Программа, которая считывает из входного файла функцию и выводит в выходной файл все корни функции.
Уравнение с одной
неизвестной может иметь несколько корней. Это может приводить к нескольким
решениям, а может и не приводить. Легко можно представить себе ситуацию, когда
в квадратном уравнении используется переменная - длина какого-либо отрезка. Один из корней может быть отрицательным,
при этом ясно, что вряд ли пользователя интересует решение с отрицательной
длиной, остаётся только один корень, т.е. единственное решение. Для исключения
«лишних» решений следует добавить ограничения на переменную.
Методы для поиска корней можно разделить на 2 большие группы:
К сожалению, функция численно вычисляющая сразу вектор корней в Matlab отсутствует. Есть следующие функции для поиска корней произвольной нелинейной функции:
=fzero(
,
) – ищет корень функции
, используя
в
качестве начального приближения. Если корней нет, то возникает исключение.
=fzero(
,[
]) – ищет корень функции
на
интервале [
]. При этом обязательно
и
должны
быть разных знаков, что сильно затрудняет использование этой функции в наших
целях, т.к. требуется искать экстремумы функции.
= fminbnd(
,
,
) – ищет минимум функции
на интервале [
]. При этом всегда возвращает минимальное
значение. Можно использовать её для вычисления вещественных корней, учитывая,
что минимумы
равные нулю
совпадают с корнями
.
Чтобы
найти все корни воспользуется
следующей идеей: пусть каким-либо методом найден корень
, разделим функцию
на
, теперь мы уменьшили
кратность корня
в функции
на 1. Если мы ещё раз
воспользуемся методом поиска одного корня, то теперь метод найдёт нам второй корень,
который мы так же используем для уменьшения количества корней
. И так мы найдём все
корни функции
.
Нашем программу, которая вычисляет все корни используя fminbnd:
% M-файл find_all_roots.m function find_all_roots % Cчитываемизвходногофайлафункцию [FI,mes] = fopen('roots.in','rt'); F = fgetl(FI); fclose(FI); % Ивыводимввыходнойфайлкорнифункции opt = optimset('TolX',10^(-15)); % Настройкаточностиминимизации [FO,mes] = fopen('roots.out','wt'); fprintf(FO,'Корни уравнения: %s=0\n',F); while true R = strcat('(',F,')^2'); x = fminbnd(R,-10000,10000); y = eval(F,x); if (y>0.01) break; end T = sprintf('%f',x); F = strcat('(',F,')/(x-(',T,'))'); fprintf(FO,'y(%f)=%f\n',x,y); end fclose(FO);
Программа считывает исходные данные из файла roots.in и выводит найденные корни в файл roots.out. Оболочка на Delphi должна была бы помещать уравнения для решения в файл roots.in, вызывать Matlab-программу и считывать результаты из roots.out. Т.е. эти 2 файла образуют интерфейс между оболочкой на Delphi и вычислительной программой на Matlab.
К сожалению, данная версия Matlab хоть и позволяет откомпилировать (т.е. создать exe-файл) find_all_roots.m, полученный файл find_all_roots.exe не работает (создатели Matlab ещё не доделали эту возможность).
Таким образом, не удалось создать систему, в которой пользователь мог бы выполнять все операции в Delphi-оболочке и вообще не запускать Matlab.
Для
символического решения уравнений вида в Matlab существует функция solve. Её синтаксис таков:
=solve(
,
) либо просто
=solve(
).
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.