Материал: Matlab. Практический подход. Самоучитель

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Глава 8. Обработка данных

Другими словами, по набору значений xk и yk (индекс k = 1,2,...,n ) нужно вычислить параметры a и b такие, чтобы зависимость f(x) = a exp(bx) наилучшим образом описывала эту зависимость. Пикантность ситуации в том, что функция f(x) = a exp(bx) нелинейным образом зависит от параметров a и b . Поэтому применяем военную хитрость и рассматриваем табулированную функцию со значениями zk = ln(yk ) в узловых точках xk (индекс k = 1,2,...,n ). Если исходная табулированная функция аппроксимируется зависимостью f(x) = a exp(bx), то новая функция записывается зависимостью F(x) = ln(f(x)) = ln(a) +bx , то есть зависимость линейная. Поэтому схема вычислений в данном случае такая:

На основе табулированных значений xk и yk (индекс k = 1,2,...,n ) создаем новую табличную зависимость xk и zk = ln(yk ) (индекс

k= 1,2,...,n ).

Для табличной зависимости xk и zk (индекс k = 1,2,...,n ) строим аппроксимирующую зависимость вида F(x) = c +bx . Находим коэффициенты b и c .

Параметр a исходной модели связан с рассчитанным параметром c соотношением a = exp(c).

Пример вычислений, выполненных в соответствии с описанной схемой, приведен ниже (рис. 8.17).

Рис. 8.17. Нелинейная аппроксимация: простой случай

Командой x=0:10 создается набор узловых точек. Значения табулированной функции в узловых точках определяем командой

331

Самоучитель Matlab

y=3*exp(-0.2*x)+0.4*sin(pi*x/5). В данном случае использована функциональная зависимость y(x) = 3 exp(−0.2x) + 0.4 sin(πx 5) . Эта зависимость близка к экспоненциальной, но с некоторой поправкой (добавлен синус). Затем командой z=log(y) определяется новый набор точек. На основе этого набора командой p=polyfit(x,z,1) вычисляются коэффициенты аппроксимирующего полинома первой степени (линейная функция). Вычисленные коэффициенты записываются в список p. Элементы этого списка в команде a=[exp(p(2)) p(1)] используются для определения нового списка. В результате выполнения этой команды получаем следующий результат (ввод пользователя выделен жирным шрифтом):

>> a=[exp(p(2)) p(1)] a =

3.7148 -0.2795

Командой f=@(x)(a(1)*exp(a(2)*x)) определяем функциональную зависимость, на основе которой строится аппроксимирующее выражение. В этой зависимости использованы вычисленные на предыдущем шаге коэффициенты (список a). Прочий код предназначен для отображения базовых точек и аппроксимирующей кривой:

>>t=0:0.01:10;

>>plot(x,y,'rs','LineWidth',2)

>>hold on

>>grid on

>>plot(t,f(t),'b--','LineWidth',2)

Такого типа код использовался достаточно часто и особых комментариев, думается, не требует. Результат показан на рис. 8.18.

Можно полагать, что результат достаточно приемлемый. И получен он минимальными усилиями. Тем не менее, такой простой путь не всегда возможен.

В случае, если задачу к линейной свести не удастся, можно воспользоваться, например, встроенной функцией fminsearch(), предназначенной для поиска минимума функции нескольких переменных. Первым аргументом функции fminsearch() передается указатель на минимизируемую функцию, а также список начальных приближений для параметров этой функции. Поэтому общий подход может быть таким: если необходимо вычислить параметры ap (индекс p = 1,2,...,m ) функции f (x,a1,a2,...,am ) на

основе табличных значений (xk,yk ) (индекс k = 1,2,...,n ), то минимизиро-

n

вать будем функцию Φ(a1,a2,...,am ) = (yk f (xk,a1,a2,...,am ))2 по па-

k =1

раметрам a1,a2,...,am . Реализация этого подхода проиллюстрирована в следующем примере. Обратимся к документу, представленному на рис. 8.19.

332

Глава 8. Обработка данных

Рис. 8.18. Результат аппроксимирования исходной зависимости

Рис. 8.19. Аппроксимация на основе нелинейной функции

333

Самоучитель Matlab

Весь командный код приведен ниже (жирным шрифтом выделен ввод пользователя):

>>x=0:10;

>>y=5*exp(-0.1*x).*sin(0.3*x)+0.3*cos(pi*x/2);

>>f=@(x,a)(a(1)*exp(a(2)*x)).*sin(a(3)*x);

>>F=@(a)sum((y-f(x,a)).^2);

>>a0=[1 -1 1];

>>a=fminsearch(F,a0)

a =

4.4322

-0.0735

0.3094

>>t=0:0.01:10;

>>plot(x,y,'rs','LineWidth',2)

>>hold on

>>grid on

>>plot(t,f(t,a),'b-','LineWidth',2)

На рис. 8.20 показан график с базовыми точками и аппроксимирующей кривой, построенной на их основе.

Рис. 8.20. Результат нелинейной аппроксимации

Теперь проанализируем командный код и полученный результат. Командами x=0:10 и y=5*exp(-0.1*x).*sin(0.3*x)+0.3*cos(pi*x/2)

создаются списки из базовых точек для создания на их основе ап-

334

Глава 8. Обработка данных

проксимирующей зависимости. При этом функциональная зависимость, которая использовалась для создания базовых точек, имеет вид y(x) = 5 exp(−0.1x)sin(0.3x) + 0.3 cos(πx 2). Командой f=@(x,a) (a(1)*exp(a(2)*x)).*sin(a(3)*x) создается функция, которая используется для создания аппроксимирующей зависимости. Мы используем

функцию f (x,a1,a2,a3) = a1 exp(a2x)sin(a3x). Параметры a1 , a2 и a3 необходимо найти. Для этого командой F=@(a)sum((y-f(x,a)).^2) создаем

функцию, которая зависит от искомых параметров и представляет собой сумму квадратов отклонений аппроксимирующей функции от табулированных значений в узловых точках. Эта функция должна принимать минимальное значение. Именно эту функцию будем минимизировать. Предварительно командой a0=[1 -1 1] создаем список начальных значений для искомых параметров модели. После этого вычисляем вектор параметров оптимизации командой a=fminsearch(F,a0). Прочие команды предназначены для отображения на графике базовых точек и аппроксимирующей кривой.

На заметку

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

Генерирование случайных чисел

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

К/ф "Клуб самоубийц, или Приключения титулованной особы"

Достаточно важной с прикладной точки зрения является задача по генерированию случайных чисел. Обычно генерировать случайные числа приходится в процессе моделирования различных процессов. В любом случае, необходимость в генерировании случайных чисел возникает намного чаще, чем это может показаться на первый взгляд. Здесь мы рассмотрим самые простые приемы, которые не подразумевают использования специальных пакетов инструментов (благо, в Matlab недостатка в таких пакетах нет – например, пакет Statistics). Мы обойдемся несколькими функциями. В первую очередь это функция rand(), которая позволяет генерировать (псевдо)случайные равномерно распределенные действительные числа. У функции есть несколько вариантов вызова. Если вызвать функцию без аргументов (инструкция rand()), в качестве результата возвращается дей-

335

Источник: https://studfile.net/preview/16433384/