Elettracompany.com

Компьютерный справочник
70 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Метод простых итераций matlab

Программная реализация метода простой итерации для решения СЛАУ в пакете MATLAB

Входные параметры: U – расширенная матрица коэффициентов, eps – требуемая точность решения.

Function res = Jakobi(U,eps);

error (‘Неверно задана система’);

%приведение системы к диагонально доминирующему виду

error(‘Система не совместна’);

%сумма по строкам

%первая норма по строкам

%сумма по столбцам

if k 1) && (max_norm2>1) && (max_norm3>1))

error(‘Введенная матрица не является диагонально преобладающей’)

%нахождение суммы для Х1(i)

sum = sum + ( A(i,j) * X0(j) );

while ( abs( X0(i) — X1(i) ) > eps )

%нахождение суммы для Х1(i)

sum = sum + ( A(i,j) * X0(j) );

%вывод вектора решений

%вывод числа итераций для выполненияусловия точности

ВСТРОЕННЫЕ ФУНКЦИИ ПАКЕТОВ MATHCAD И MATLAB

ДЛЯ ПРИБЛИЖЕННОГО РЕШЕНИЯ СИСТЕМ ЛИНЕЙНЫХ

АЛГЕБРАИЧЕСКИХ УРАВНЕНИЙ

Пакет MATHCAD

Решение систем линейных уравнений – довольно распространенная задача. Для системы линейных уравнений, заданной в матричном виде AX=B, вектор решения можно получить из очевидного выражения X=A-1B, или, например, из решения системы уравнений с проверкой на невырожденность матрицы:X:=if(|A|,A -1 B,0).

Следует обратить внимание на то, что пакет содержит и встроенную функцию решения линейных систем lsolve(A,B), где А– матрица коэффициентов, а В – вектор свободных членов. Пример использования предложенных методов показан на рис. 5.1.

Рис. 5.1. Примеры решения системы

Для решения систем уравнений, систем неравенств, смешанных систем служат решающие блоки. Структура решающего блока:

начало | Given

тело | несколько конструкций вида АВ1 оп АВ2

(оп – некоторая операция отношения, причём для написания знака равенства используется особый «жирный» знак равенства, который находится на панели инструментов; знак присваивания в теле решающего блока не используется)

конец | FIND (список) или MINERR (список).

Список – это перечень переменных, которые необходимо найти.

С помощью FIND ищут точное решение; если оно отсутствует, то возникает ошибка. Посредством MINERR всегда будет найдено решение, минимизирующее невязку ограничений. Переменная ERR– величина ошибки.

Перед решающим блоком необходимо задать начальные условия для всех искомых переменных, можно в векторном виде. Соответственно, в теле решающего блока можно использовать запись уравнений в матричном виде. Максимальное количество уравнений в системе доведено до двухсот. Часто приходится решать системы уравнений при наличии определенных ограничений. Таким образом, в теле решающего блока могут быть одновременно как равенства, так и неравенства. Пример такой системы приведен ниже:

Given

find (x,y) =

Для последующего использования результатов необходимо так организовать конец:

В теле решающего блока нельзя строить графики, выполнять вычисления.

Итерации производятся до тех пор, пока ôERRô£ TOL. Если встречается седловая точка и не известно, куда направлен градиент, то выдается сообщение not converging (не решаемо). Количество итераций ограничено. Возможно сообщение об ошибке вида did not find solution (не найдено решение).

При возникновении таких ошибок можно:

– изменить точность – TOL;

– заменить начальные условия;

– заменить find на minerr и получить приближенное решение.

Однако при использовании функций findи minerrнужно проявлять осторожность и обязательно предусматривать проверку решений, т.к. нередки случаи, когда решение может оказаться ошибочным.

Для получения другого решения можно поменять начальные условия, для уточнения – уменьшить TOL.

Пакет MATLAB

Рассмотрим две системы линейных уравнений: АХ=В и ХА=В. В MATLAB такие системы решаются без вычисления обратной матрицы. Два типа матричного деления / и используются для этих двух ситуаций, когда неизвестная матрица стоит слева или справа от матрицы коэффициентов:

Х=АВ соответствует решению АХ=В;

Х=В/А соответствует решению ХА = В.

При этом должны выполняться условия соответствия размерностей матриц X, А, В. Напомним, что для варианта Х=АВ матрица X должна иметь то же количество столбцов, что и матрица В, и то же число строк, сколько столбцов у матрицы А. Для Х=В/А эти условия обратны.

Алгебраические свойства оператора / можно вывести из соотношения(В/А)’ = (А’В’).

Матрица не обязательно должна быть квадратной, она может быть размером mхn. При этом существуют следующие варианты:

· m = n – квадратная система, возможно нахождение точного решения;

· m > n – переопределенная система, решение ищется с помощью метода наименьших квадратов;

· m n и ранг матрицы равен n, то каждое из трех следующих выражений вычисляет X по методу наименьших квадратов:

Х=АВ

Х=рinv(А)*В

Х=inv(А’*А)*А’*В

В противном случае решение Xпо методу наименьших квадратов не единственно и существует множество векторов, минимизирующих norm(A*X-B).Решение, вычисленное с помощью Х=АВ,– базовое решение, имеющее не больше r ненулевых компонент: r=rank(A). Решение, вычисленное с помощью Х=рinv(А)*В,– это решение с минимальной нормой X.

Решение систем нелинейных уравнений в Matlab

Технология решения систем нелинейных уравнений в среде MS Excel рассматривалась в статье. В ней рассмотрена методы приближенного решения графическим методом и уточненного решения с помощью инструмента Поиск решения. Рассмотрим эти методы решения в Matlab.

Приближенное решение систем нелинейных уравнений графическим методом в Matlab

Пример . Найти графически приближенное решение системы

в диапазоне значений х [0,2:3].
Решение.

— обозначим х 2 =у;
— теперь представим приведенные уравнения в виде системы функций

Для решения задачи воспользуемся возможностью Matlab для построения в одном окне графиков нескольких функций. Для этой цели используем функцию plot со следующей синтаксической конструкцией:

где xl, x2, xЗ,.„ — векторы аргументов функций (в нашем случае все они — х), a f1, f2, f3. —векторы значений функций, графики которых строятся в одном окне (в нашем случае они f1 и f2).
Заметим, что в отличие от Excel мы можем взять очень маленький шаг для вычисления узловых точек, так как для построения графика нам не надо создавать таблицу соответствия значения функции и аргумента.
Для построения графиков указанных функций нужно записать командном окне код инструкции:

>> x=0.2:0.01:3; f1=1-2.*x;f2=log(x);plot(x,f1,x,f2);grid on .

В результате выполнения инструкции будут построены графики (рис.1).

Значение аргумента x при котором линии полученных графиков функций пересекаются примерно равно значению 0,7, а значение функций примерно равно -0,4. Таким образом примерное решение системы получено.

Уточнение корней системы нелинейных уравнений в системе Matlab

В Matlab есть оператор fsolve , который позволяет решить систему нелинейных уравнений. Эта функция принимает вектор приближений и возвращает вектор значений функции.

Рассмотрим, как решить систему нелинейных уравнений

с помощью fsolve .

Решение .
Создадим М-файл с именем funsist.m и создадим функцию введя код (рис. 2):

В качестве значений вектора приближений, ориентируясь на ранее полученное графическое решение, возьмем вектор [0.7, -0.4],
В командном окне Matlab введем инструкцию
>> [xr, fr, ex] = fsolve(@funsist,[0.7, -0.4],optimset(‘TolX’,1.0e-2))

В этой инструкции выходными возвращаемыми значениями являются:
xr — вектор решений;
fr — это значения функций, указывающие на сколько значения функций близки к нулю, при найденном решении (т.е. точность решения);
ex- параметр сходимости, если он равен 1, то решение сошлось.

Читать еще:  Пакеты расширения matlab

В результате выполнения инструкции получим результат решения (рис.3):
xr = 0,6874 -0,3748;
fr = 1.0e-008 — точность до минус восьмого порядка;
ex=1 — сходимость есть

Можно использовать и другие подходы для решения подобных систем уравнений, таких как метод Ньютона, метод простых итераций. Эти методы будут рассмотрены в других статьях.

Технология решения нелинейных уравнений в среде MatLab

В математическом пакете MatLab имеются как программные средства для реализации алгоритмов уточнения корней уравнений, приведенных в п.6.2.2, так и встроенные функции для численного и аналитического вычисления корней уравнений.

Рассмотрим программные средства MatLabна примерах.

Пример 6.2.4-10. Локализовать корни уравнения f(x)=x 3 –cos(x)+1 средствами пакета MatLab.

Решение алгебраических и трансцендентных уравнений в среде MatLAB проще реализовать с помощью встроенных функций: solve(), fzero(), roors().

Для нахождения вещественных корней уравнений вида f(х)=0 используется функция fzero(). Алго­ритм, реализованный этой функцией, представляет собой комбинацию хорошо известного метода дихотомии (деления пополам), метода секущих и метода обрат­ной квадратичной интерполяции. В простейшем варианте обращения кроме указателя на функцию, корень которой ищется, задается окрестность х0, с которой начинается поиск: х = fzero(f, x0).

Аргументf может быть задан одним из способов:

· как формула с неизвестным х, заключенная в апострофы;

· как имя m-файла (в апострофах и без расширения m);

· как указатель на функцию (например, @f_name);

· как указатель на анонимную функцию (например, f_handie).

Необходимо обратить внимание на то, что формула, заключенная в апострофы, в качестве независимой переменной мо­жет содержать только х. Использование независимой переменной с другим именем вызовет сообщение об ошибке.

Аргумент х0 может быть задан одним из двух способов:

· как вектор [a;b], представляющий интервал (а — x + sin(x) для локализации корня.

Из графика видно, что один из корней находится на интервале [3;4]. И этой информацией естественно воспользоваться при обращении к функ­ции fzero( ):

Вместо явного задания формулы для функции f мы могли бы объявить соответствующую функцию, запомнив ее в виде автономного m-файла или включив ее в качестве подфункции в файл нашей программы.

Если мы хотим получить не только значение корня, но и узнать значение функции в найденной точке, то к функции fzero( ) можно обратиться с двумя выходными параметрами.

В ряде задач такая точность может оказаться излишней. MatLab предо­ставляет пользователю возможность формировать различные условия прекращения итерационного процесса — по точности вычисления координаты х, по модулю значения функции f(), по количеству обращений к функции f( ) и т. д.

В некоторых случаях применение функции fzero() может дать парадоксаль­ные результаты.

Пример 6.2.4-12. Найти решения tg(x) = 0 на интервале [1;2].

Якобы «корень», соответствующий приближенному значению /2, на самом деле является точкой разрыва, при переходе через которую функция меняет знак. Выведенное значение функции в найденной точке убеждает нас в том, что найден не корень.

Функцияfzero() может возвратить еще два выходных параметра.

Положительное значение e_fiag (обычно, это 1) означает, что удалось най­ти интервал, на концах которого функция f( ) меняет знак (пример с tg(x) не должен притупить вашу бдительность). Если такой интервал не обнару­жен, то e_fiag=-1. Структура inform содержит три поля с именами iterations, funcCount и algorithm. В первом из них находится количество итераций, выполненных при поиске корня, во втором – количество обра­щений к функции f( ), в третьем – наименование алгоритма, использован­ного для нахождения корня.

Итерационные методы

Сложные неэволюционные задачи и их разностные схемы Ау = -/ обычно решаются итерационными методами. Разберем один из таких методов на примере двумерного уравнения (12.43). Простейшим методом является метод Якоби, относящийся к семейству методов последовательных приближений. Процедуру решения с помощью этого метода можно представить в следующем виде:

где s — номер итерации. Уравнение (12.57) перепишем в форме

Метод Якоби и большинство других итерационных методом можно представить в следующей форме:

Когда В и т в (12.59) нс зависят от s, итерационный процесс называют стационарным. Итерационный процесс (12.59) можно рассматривать как разностную схему некоторой эволюционной задачи. Физический смысл построенной эволюционной задачи не имеет смысла, важно лиши то, чтобы счет на установление состоялся. Несущественно то, что именно аппроксимирует оператор В. существенно лишь то, чтобы: 1) он обеспечивал максимально быстрое затухание начальных данных и 2) легко обращался за малое число операций. Продольно-поперечная и локально-одномерная схемы, рассмотренные с точки зрения того, что они являются итерационными процессами, удовлетворяют двум перечисленным выше условиям.

Протестируем итерационную схему Якоби (12.57) на примере численного решения уравнения

которое, как нетрудно проверить, при соответствующем подборе граничных условий имеет аналитическое решение

В листинге 12.8 приведен код программы численного решения уравнения (12.60) итерационным методом Якоби согласно схеме (12.57).

%Программа численного решения двумерного %эллиптического уравнения (12.60) итерационным %методом Якоби по схеме (12.57) clear all

%3адаем максимальное число итераций itermax=300;

%Определяем габариты области по направлениям %х1 и х2 а=1; Ь=1;

%Определяем число узлов сетки по координатам %х1 и х2, а также шаги сетки Ы и h2 %и вспомогательные величины rl, г2, гЗ N=51; М=51;

Ь1=а/(N-l); h2=b/(M-l); rl=0.5/(1+(hl/h2) л 2); г2=0.5/(1+(h2/hl) л 2); г3=0.5/(hl A (-2)+h2 A (-2)); xl=0:hl:a; x2=0:h2:b;

%Определяем аналитическое решение (12.61) for n=l:N

%Определяем начальную итерацию for n=l:N

%Определяем граничные условия при х2=0 и х2=Ь for s=l:itermax for n=l:N

у(s,n,l)=(xl(n)-0.5*a) л 2+(x2(1)-0.5*b) л 2; у(s,n,M)=(xl(n)-0.5*a) л 2+(x2(M)-0.5*b) л 2;

%Определяем граничные условия при xl=0 и х1=а for s=l:itermax for m=l:M

у(s, l,m) = (xl(1)-0.5*a) л 2+(x2(m)-0.5*b) л 2; у(s,N,m)=(xl(N)-0.5*a) л 2+(x2(m)-0.5*b) л 2;

%Определяем ошибку начального приближения как разность %численного и аналитического решений в норме С for n=l: N

z (n, m) =abs (у (1, n, m) -u (n, m) ) ;

%Организуем цикл основного итерационного %процесса в методе Якоби for s=2:itermax for n=2: (N-l)

%Определяем ошибку как разность численного %и аналитического решений в норме С for n=l:N

z (n, m) =abs (y (s, n, m) -u (n, m) ) ;

%Рисуем численное решение уравнения (12.60)

%на последней итерации subplot(1,2,1); surf(х2,xl,z);

%Рисуем кривую зависимости ошибки численного %решения от номера итерации subplot(1,2,2); plot(1:itermax,error);

Код листинга 12.8 генерирует итоговый график, вид которого представлен на рис. 12.8. На рис. 12.8, а приведено трехмерное изображение численного решения на последней итерации (.v = smax). Численное решение весьма близко аналитическому решению (12.61). На рис. 12.8, б кривая зависимости ошибки численного решения, рассматриваемой как разность численного и аналитического решений в норме II • Нс , т. е. error = II y’ s) — и llf , от номера итерации s = = 1, . smax. Видно, что ошибка по мере увеличения числа итераций уменьшается, но довольно медленно.

Читать еще:  Matlab нечеткий регулятор

Рис. 12.8. Численное решение задачи (12.60) методом последовательных приближений Якоби (а) и кривая зависимости численной ошибки от номера итерации (б)

Попеременно-треугольную схему рассмотрим на примере численного решения двумерного уравнения вида

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

Для численного решения (12.63) составим разностную схему, шаблон для которой представлен на рис. 12.9 в виде сплошных и пунктирных линий.

Рис. 12.9. Шаблон разностной схемы (12.64)

Разностная схема на рис. 12.9 является полностью неявной, она имеет вид:

Разностная схема (12.64) может быть переписана в канонической форме:

Схема (12.65) не является экономичной, поскольку для обращения оператора Е- тЛ, -тЛ, требуется, как отмечалось выше,

/V 4 операций в расчете на 1 узел сетки.

Введем “треугольные” операторы

определенные на треугольных шаблонах, которые представлены на рис. 12.9. Очевидно, что Л, + Ai = -(/?i + Ki_), тогда разностную схему (12.65) можно переписать в виде:

Немного изменим схему (12.66), добавив в ее левую часть член vRtR,(у-у)/г , который имеет второй порядок малости 0( г 2 ). Возникнет оператор E + xRt +тЛ, +т, который можно представить в виде произведения (? + тЛ,)(? + т?,), т. е. говорят, что оператор факторизуется. В итоге получается схема, которую называют попеременно-треугольной:

Операторы Е + zR и ? + rR< легко обращаются с помощью процедуры бегущего счета, разобранной в лекции 10 при изучении численного решения уравнений переноса. Алгоритм расчета при процедуре бегущего счета несложен и требует небольшого числа операций в расчете на 1 узел сетки. Попеременно- треугольная схема переносится на случай любого числа измерений, она может быть обобщена, если коэффициенты уравнения переменные и даже разрывные, а область интегрирования имеет сложную форму.

Проведем конкретный численный расчет с помощью попеременно-треугольной разностной схемы, решая уравнение (12.62) с правой частью вида

Нетрудно проверить, что решением задачи (12.62), (12.68) в области G = |0,я]х[0,/;>] является выражение:

Перепишем разностную схему (12.67) в следующем виде:

где введено вспомогательное решение w. Распишем систему разностных уравнений более подробно

Уравнение (12.71) решается методом бегущего счета с помощью перехода от точки (.vj |, л’2 [) к точке (.v12, л.|) и т. д. к точке (xbV-i, -V2.1) и далее после перехода на новый слою по переменной х2 от (xu, х2Д к (X|jV_i, х21) и т. д. вплоть до точки (л’1Л;_|, -V2 V/-i). Движение бегущего счета согласно уравнению (12.71) состоит в движении слева направо и снизу вверх. Движение счета согласно уравнению (12.7Г) обратное предыдущему случаю, т. е. отточки (a’i,v-i>x2_w-i) справа налево и сверху вниз до точки (Х| ь х>Д. С учетом аналитического решения (12.69) в качестве граничных условий задачи (12.62), (12.68), принимаем

Кроме того, при решении уравнения (12.71) в качестве граничных условий для переменной w, принимаем

где имеется в виду пространственная сеткаХ| „ = nh, п = 0,1, . л, x2j„ = ш/г2, т = 0,1, . М.

В листинге 12.9 приведен код программы, которая численно решает задачу (12.62), (12.68), (12.72) попеременно-треугольным способом по схеме (12.71), (12.71′), (12.72′).

%Программа численного решения задачи (12.62),

% (12.68), (12.72) попеременно-треугольным способом

function triangle global a b kl k.2

%Определяем габариты области интегрирования и %константы kl, k2, входящие в уравнение (12.62) а=1; b=l; kl=l; k2=l;

%Определяем число узлов сетки и шаги Ы, Ь2

%по переменным xl, х2 N=35; М=35;

%Определяем шаг в итерационной схеме на %установление и число шагов на установление tau=0.001; Nt=30;

г1=(tau*kl)/Ь1 л 2; r2=(tau*k2)/Ь2 Л 2; гЗ=1+г1+г2;

%Определяем начальное распределение for n=l:N

%Определяем нижнее и верхнее граничные условия for t=l:Nt

%Определяем левое и правое граничные условия for t=l:Nt

%Оцениваем ошибку отличия численного решения %от аналитического в норме С for n=l:N

z (n, m) =abs (у (1, n, m) -u (xl (n) , x2 (m) ) ) ;

%Организуем основной цикл итераций на установление for t=2:Nt

%Находим промежуточное решение w согласно (12.71) for m=2:(М-1)

%Находим решение на следующем слое согласно (12.71′) for m=(М-1) :-1: 2

%Оцениваем ошибку отличия численного решения %от аналитического в норме С for n=l:N

z (n, m) =abs (y (t, n, m) -u (xl (n) , x2 (m) ) ) ;

%Рисуем профиль численного решения на последнем шаге %итерации

subplot (1,2,1); surf (х2,xl,z);

%Рисуем профиль ошибки численного решения от номера %шага итерации

subplot (1,2,2): plot(1:Nt,error);

%Определяем функцию правой части (12.68) function y=f(xl,x2) global a b kl k.2

y=-2*k2* (xl-0.5*a) A 2-2*kl* (x2-0.5*b) A 2;

%Определяем аналитическое решение (12.69) function y=u(xl,x2) global a b

На рис. 12.10 приведен итог работы кода программы листинга 12.9. На рис. 12.10, а приведен трехмерный профиль численного решения по схеме (12.71), (12.7Г) задачи Дирихле (12.62), (12.68), (12.72) попеременнотреугольным способом. Трехмерный профиль приведен для численного решения полученного на последнем шаге итерационного процесса, это решение весьма близко к аналитическому решению (12.69) исходной задачи.

Рис. 12.10. Решение задачи Дирихле (12.62), (12.68), (12.72) попеременнотреугольным способом

На рис. 12.10, б приведена зависимость ошибки численного решения от номера шага итерационного процесса, т. е. error = II у 1 «-и Нс, где 1 = 1, . fmax — номер итерации.

Восстановление простых линейных и итерационных функций средствами MATLAB

Рубрика: Технические науки

Дата публикации: 03.02.2017 2017-02-03

Статья просмотрена: 104 раза

Библиографическое описание:

Петров Е. Н., Петрова А. Ф. Восстановление простых линейных и итерационных функций средствами MATLAB // Молодой ученый. — 2017. — №5. — С. 52-55. — URL https://moluch.ru/archive/139/39180/ (дата обращения: 06.04.2020).

В данной статье рассматривается метод восстановления простых функций, сохраненных в виде p-файлов, средствами MATLAB. В качестве основного инструмента используется встроенный отладчик и функция dbstop. Применение описанных в статье методов позволяет восстановить утраченные исходные коды простых линейных и итерационных функций.

MATLAB позволяет сохранить откомпилированные М-функции в виде p-кода [1]. В таком случае в дальнейшем функция будет представлять собой “чёрный ящик”: пользователь будет иметь дело только с введёнными им данными и с возвращаемым результатом. Однако в ряде случаев может потребоваться обращение к исходному коду функции. Например, исходный код, необходимый для работы, может быть утерян, а производить какие-либо изменения в коде функции, сохранённой в виде p-файла, не представляется возможным. В статье будет рассмотрен способ восстановления исходного кода функции по p-коду средствами MATLAB, не подразумевающими попытки вскрыть шифр либо алгоритм кодирования, используемые в данной среде для хранения откомпилированных функций. Описанный в данной работе метод основан на анализе данных, получаемых в результате работы с p-файлом в среде MATLAB, подборе значений, выявлении зависимостей.

Читать еще:  Цвета в matlab

В качестве аппроксимации неизвестной функции, заданной множеством значений аргумента и соответствующими им выходными значениями функции, может выступать многочлен, генерируемый на основе имеющихся пробных точек, но ошибка может быть весьма велика, а если функция принимает на вход вектор произвольной длины, то такая аппроксимация невозможна. Поэтому мы будем говорить о восстановлении исходной функции.

Прежде всего, необходимо выяснить, какие аргументы принимает функция, если это заранее не известно. Будем подавать аргументы разных типов, в т. ч. вектора, и наблюдать, как это влияет на результат [2].

Далее приступим собственно к восстановлению функции. Для решения поставленной задачи нам потребуется функция dbstop [3], позволяющая пошагово отлаживать функции. Использовать её можно следующим образом:

Как видно в примере, dbstop может иметь два аргумента, однако второй не является обязательным. Если не указать номер строки кода для точки останова, функция остановится на второй строке.

Если введённый номер строки кода превосходит длину функции, выводится следующее сообщение об ошибке:

Error using dbstop

You cannot set a breakpoint past the start of the last expression in the file.

Таким образом, путём подстановки разных значений можно выяснить длину кода функции в строках.

Далее, применяя всё ту же функцию dbstop, выясним, какие использованы переменные и каким образом изменяются их значения. Для этого сначала вызовем функцию dbstop для нашего файла, а затем вызовем саму целевую функцию для допустимого набора аргументов:

Переход к следующей строке кода осуществляется нажатием на клавишу F10. В окне Workspace появляются имена и значения переменных, пример такого окна представлен на Рис. 1. Некоторые закономерности можно выявить уже на этом этапе, обратив внимание на имена переменных, порядок их появления и изменения. Так, например, можно выяснить, где в функции присутствует цикл, значения каких переменных в его теле изменяются. Также можно выявить переменные-флаги и участки кода, выполнение которых зависит от значений этих флагов. Таким образом, отладка при помощи dbstop позволит найти циклические и условные конструкции, если они есть. Целесообразно пробовать подавать на вход разные наборы аргументов, чтобы охватить как можно больше предусмотренных в целевой функции вариантов их обработки. Кроме того, на последнем шаге обнаруживается переменная, в которую записывается результат, возвращаемый функцией.

Выход из режима отладки либо переход к следующей точке останова осуществляется нажатием на клавишу F5.

Рис. 1. Вид окна MATLAB во время отладки

Очевидно, полученная на предыдущих этапах информация не позволяет в полной мере восстановить исходный файл. Установив количество, имена, порядок обновления переменных, мы можем приступить к выявлению зависимостей между ними, то есть к восстановлению конкретных выражений, присваиваемых им. Получив все эти зависимости, мы решим поставленную задачу — восстановим исходную функцию.

Помимо наблюдения за пошаговым исполнением функции, режим отладки позволяет на любом шаге вручную изменять значения имеющихся переменных при помощи обычного присваивания. Используя эту возможность, будем выявлять зависимости между переменными. Для этого запишем значения всех переменных на интересующем нас шаге (целесообразно выбрать первое обновления значения интересующей переменной). Затем, изменяя значения других переменных, выясним, какие из них влияют на целевую переменную, то есть вероятнее всего присутствуют в присваиваемом ей выражении. Когда обнаружены все такие переменные, можно восстанавливать саму искомую формулу.

Проще всего обнаружить, какие переменные входят в искомую формулу в качестве слагаемых. Очевидно, изменение их значений влечёт за собой эквивалентное изменение значения целевой переменной. Аналогично находятся и свободные множители. Также несложно найти переменные, чья разность входит в формулу как множитель: если задать значения этих переменных равными, то целевая переменная всегда будет обращаться в ноль либо сохранит лишь часть, являющуюся свободным слагаемым. На этом же этапе выявляются и делители, если таковые имеются: деление на ноль даёт бесконечность (в MATLAB обозначается как Inf).

Сложнее обнаружить менее очевидные зависимости: множители, содержащие выражения из переменных в показателе степени, тригонометрические функции и т. д. Рассмотрим, как это можно сделать. Для линейных функций подобные выражения восстановить достаточно просто, поэтому мы будем говорить об итерационных функциях.

Целесообразно записывать значения искомого коэффициента от итерации к итерации. Чтобы найти такое значение, нужно результирующую переменную разделить на все известные сомножители (значения известных сомножителей должны быть актуальны для данного шага цикла, если это переменные). Далее будем искать зависимость между значениями искомого коэффициента. Если разность или отношение этих значений постоянны, то задача практически решена: остаётся выяснить, входят ли эти разности или отношения в формулу как значение некоторой переменной или представляют собой постоянное число. Проанализировать число можно при помощи вопросно-ответной системы WolframAlpha [4, 5], дающей возможность узнать, является ли данное число некоторой правильной дробью или степенью числа, результатом тригонометрической функции и т. д. Поэтому для большей точности необходимо использовать для вычислений формат записи чисел с большим количеством знаков — format long [6].

Если зависимость между коэффициентами неочевидна, можно снова пробовать искать входящие в множитель переменные оговоренными выше способами: ведь отдельные множители или выражения в скобках могут быть возведены в степень. Кроме того, можно при пошаговом выполнении цикла сбрасывать значения обновляющихся переменных на начальное, чтобы выяснить механизм их обновления и влияние на искомую формулу. При таком анализе переменных должна выявиться искомая формула.

Когда все значения уже найдены, испортить картину может подача на вход функции другого набора аргументов. Если ранее идеально совпадавшие целевая и составленная нами функции теперь дают отличные друг от друга результаты, значит, не учтено влияние какой-то переменной, например, отвечающей за длину входного вектора или хранящей индекс элемента этого вектора. Восстановив функцию в полном объёме, мы окончательно решим поставленную задачу.

Подведём итог, представив описанный алгоритм в виде схемы на Рис. 2.

Рис. 2. Алгоритм восстановления функции

Следует отметить, что рассмотренный метод не даёт стопроцентной гарантии получения результата. Также неэффективен он и для восстановления длинных функций с большим количеством строк кода. Однако для небольших функций, как линейных, так и итерационных, имеющих условные конструкции и неочевидные формульные зависимости между переменными, такой способ восстановления даёт хорошие результаты. Разумеется, процесс восстановления долог и трудоёмок, однако других способов восстановить утерянный исходный код без декомпиляции не существует.

Ссылка на основную публикацию
ВсеИнструменты 220 Вольт
Adblock
detector
×
×