- •Практикум по ядру пакета matlab 7.2 r2006a
- •Введение
- •Лабораторная работа №1 Знакомство с пакетом matlab 7.2.
- •1. Структура пакета и принципы работы
- •Пример:
- •Задание:
- •Лабораторная работа №2 Проведение вычислений без м-файлов
- •1. Элементарные матричные вычисления.
- •Пример:
- •Задание
- •2. Элементарные функциональные вычисления и построение графиков.
- •Пример:
- •Сформировать случайные векторы u и V размера 1×4.
- •Составить анонимную функцию для вычисления площади треугольника по формуле Герона ( , p- полупериметр, a,b,c – стороны). Вычислить площадь для египетского треугольника.
- •Построить контурный график на основе базиса (u,V) и матрицы значений в, которая содержит высоты «гор». Площадь построения – [-2;2]× [-2;2].
- •Создать киноленту, отображающую эволюцию поверхности треугольников при изменении третьей стороны треугольника.
- •Задание:
- •Лабораторная работа №3 Проведение вычислений с помощью м-файлов
- •1. Создание и отладка м-файлов.
- •Пример:
- •Записать в виде м-функции вычисления по формуле Герона в файле geroncore. Вычислить площадь при наборах (1,2,1.5) и (1,2,4).
- •Записать в виде м-функции MyTriangle решатель треугольника, т.Е. По трем заданным его элементам находящий остальные – число аргументов и результатов переменное.
- •Задание:
- •Пример:
- •Составить м-функцию, содержащую несколько независимых вложенных функций. Параметров вызова два – строковая переменная s, по которой определяется вызываемая подфункция, и массив коэффициентов к.
- •Вычислить объем n-мерной сферы радиуса 1. Вывести график зависимости V(n).
- •А) Графически решить систему уравнений (a,b – параметры):
- •Решить систему обыкновенных дифференциальных уравнений и начертить траекторию движения частицы (параметр а изменяется от -1 до 1 с шагом 0.5):
- •Задание:
- •В рамках того же м-файла реализовать вычисление лапласиана от функции:
- •В рамках того же м-файла реализовать построение 4-х графиков на одном полотне: 1,2,3d-мерного и одного параметрического. На базе данных от функции u1,2(X,y,z).
- •Лабораторная работа №4 Реализация вычислений с помощью графического интерфейса (gui)
- •Пример:
- •В масштабируемом окне создать интерфейс, содержащем большинство элементов палитры, с целью адаптировать его к программе MyTriangle (см. Пример №3 Лабораторной работы №3, часть 1).
- •Реализовать «решение треугольника» и более сложные функции в gui-программе
- •Задание:
- •Реализовать на базе Примера игру «о, счастливчик» с собственным gui-интерфейсом. Дополнительные примеры Матричные комплекснозначные вычисления
- •Решения
Пример:
Построить и оформить графики трех функций
,
w(t)=z(t)-y(t)
на [0;3]. Из серии набранных команд собрать
М-файл-сценарий.
Создадим анонимные функции
>> funy=@(x) (x.^2).*log(x+eps)+(1+x.^2).^(1/3);
>> funz=@(x) (1+x.^3)./(1+x.^2); funw=@(x) funz(x)-funy(x);
Проверим правильность задания
>> X=[0 1 2];[funy(X); funz(X); funw(X)], clear('X')
ans =
1.0000 1.2599 4.4826
1.0000 1.0000 1.8000
0 -0.2599 -2.6826
Строим графики простейшим путем
>> figure(1);hold on;fplot(funy,[0 3],'-y');fplot(funz,[0 3],'--r');fplot(funw,[0 3],':g');hold off
С помощью контекстного меню (Create…) в History Commands формируем М-файл текущей сессии (лишние команды можно затем стереть в редакторе)
Проведем украшение графика (скажем, заменим желтый цвет линии на синий и добавим легенду). Исполним пункт File/Generate M-file. Откроется новый файл Untitled-2. Скопируем все секции оттуда (кроме первой, начиная со строки %Create Figure). Сохраним файл под именем MyGraph.m в текущий каталог.
К
сожалению, несмотря на полезные
конструкции сгенерированного кода, он
был исполнен в виде функции, поэтому
придется провести ряд изменений, чтобы
сделать его работоспособным. В первой
секции заменим figure1 = figure()
на set(gcf, - ведь полотно
графиков уже создано. Во второй секции
первая строка приобретет вид
set(gca,'Color',[0.502 1 1]);. Также
следует убрать третью ось в команде
прорисовки осей axis. С
секциями «% Create plot» сложнее, здесь
придется операцию создания кривой
заменять на поиск указанной кривой и
установку ее свойств (см . findobj).
Это позволит нам заменить все «пустые»
ссылки (дескрипторы).
Общий вид кода и смасштабированного результата его выполнения (по команде MyGraph в консоли) см. на рис. снизу и слева.
Записать в виде м-функции вычисления по формуле Герона в файле geroncore. Вычислить площадь при наборах (1,2,1.5) и (1,2,4).
function S=geroncore (a,b,c)
p=(a+b+c)/2;
S=sqrt(p.*(p-a).*(p-b).*(p-c));S=real(S);
end
>> geroncore ([1 1],[2 2],[1.5 4])
ans =
0.7262 0
Записать в виде м-функции MyTriangle решатель треугольника, т.Е. По трем заданным его элементам находящий остальные – число аргументов и результатов переменное.
Приготовим шаблон М-файла, разобьем его на секции (см. иконку «%%+» на второй панели редактора) и сразу его запишем
function [MyS, varargout]=MyTriangle (varagrin)
% Эта функция "решает" треугольник. Стандартный вызов предусматривает
% 4 входных и 4 выходных аргумента. Первые три аргумента - длины трех
% сторон, четвертый - строка вида 'abA', где большими буквами указаны
% углы, а малыми - стороны (угол А противолежит стороне а). Пятый аргумент
% предусматривает дополнительный расчет биссектрис, медиан или высот.
%%
% Основные внутренние переменные
a=1;b=1;c=1;A=60;B=A;C=A;MyS=0;MyLegend='abc';
%%
%Проверка данных
%%
%Запись данных
%%
%Вычисление результата
%%
%Вывод результатов
varargout(1)=varargin(1);
end
Будем наполнять содержание каждой секции. Начнем предварительную проверку данных. При желании формат данных можно выверять тщательнее. Пока же проверяем число аргументов и формат легенды, которая пишется как массив символов в MyLegend. Для примера мы сохранили закомментированную «точку останова» keyboard. Особенность переменной varargin состоит в том, что она является массивом ячеек (cell array), типом промежуточным между классической записью и массивом. Поэтому для извлечения данных используется функция char. Проще, но менее привычно, было бы записать varargin {4} вместо varargin(4).
%Проверка данных
switch nargin
case {0,1,2}
warning('Слишком мало аргументов'), flag=false;
case {6,7,8}
warning('Слишком много аргументов'), flag=false;
otherwise
flag=true;
if (nargin~=3) MyLegend=char(varargin(4)); end;
%keyboard;
end;
if (~flag) return; end;
MyLegend=MyLegend(1:3);flag=true;NAngles=0;
for s=MyLegend
switch s
case {'a','b','c'}
case {'A','B', 'C'}
NAngles=NAngles+1;
otherwise
flag=false;
end;
if (~flag) break; end
end;
if (NAngles==3) error('По трем углам нельзя решить треугольник'),
return; end;
if (~flag) error('Неправильный формат легенды данных'), return; end;
Для записи данных используем простой цикл и полезную команду eval.
%Запись данных
for (j=1:3) eval(strcat(MyLegend(j),'=',num2str(varargin{j}),';')); end;
Для расчета нам нужно разделить секцию на две части, в первой – описания функций, а во второй – вызывающий их код. Заключительная команда вызывает функцию geroncore из одноименного М-файла. Мы также оставили точку останова keyboard; поучительно рассмотреть одинаково называющиеся переменные, имеющие разную область действия – см. во время второго останова селектор Workspace-Stack. В стеке функции b=5, а стеке программы b=4 – интерпретатор не путается в действии принципа «локальное имя закрывает глобальное». Теперь программу можно осмысленно запускать, временно раскомментаривая последнюю строчку – например, >> MyTriangle(3,4,5,'abc').
% Сначала список функций, математически все сводится к 5 случаям
%%
% Теорема синусов. Два угла прилежат стороне.
% Находится сторона у первого угла
function res=SIN_side (a,alfa,beta)
if (alfa+beta>180) warning('Два тупых угла невозможны');
res=NaN;return;
end;
res=a.*sin(deg2rad(beta))./sin(deg2rad(alfa+beta));
end
% Теорема косинусов. Находится сторона возле угла
function res=COS_side (b,c,gamma)
a1=c.^2-(b.*sin(deg2rad(gamma)))^2;
if (a1<0) warning('Такого треугольника не существует');
res=NaN;return;
end;
a2=b+sqrt(a1);a1=b-sqrt(a1);
if (a1<0) warning('Найдено два таких треугольника!'); end;
res=a2;
end
% Теорема косинусов. Находится сторона против угла
function res=COS_opposite (a,b,gamma)
res=sqrt(a.^2+b.^2-2*a.*b.*cos(deg2rad(gamma)));
end
% Теорема косинусов. Находится угол (в градусах)
function res=COS_angle (a,b,c)
if ((a<eps)||(b<eps)||(a+b<c))
warning('Не выполнено неравенство треугольника');
res=NaN;return;
end;
keyboard;
res=acosd((a.^2+b.^2-c.^2)./(2*a.*b));
end
%%
% Главный блок расчета
switch MyLegend
case 'abc'
C=COS_angle(a,b,c); if(C==NaN) return; end;
B=COS_angle(a,c,b); if(B==NaN) return; end;
A=COS_angle(c,b,a); if(A==NaN) return; end;
case 'abC'
c=COS_opposite(b,a,C);if(c==NaN) return; end;
B=COS_angle(a,c,b); if(B==NaN) return; end;
A=180-B-C;
case 'abA'
c=COS_side(b,a,A);if(c==NaN) return; end;
B=COS_angle(a,c,b); if(B==NaN) return; end;
C=180-A-B;
case 'aBC'
b=SIN_side(a,C,B);if(b==NaN) return; end;
c=COS_opposite(a,b,C);if(c==NaN) return; end;
A=180-B-C
case 'aAB'
C=180-A-B; if(C<0) return; end;
b=SIN_side(a,C,B);if(b==NaN) return; end;
c=COS_opposite(a,b,C);if(c==NaN) return; end;
otherwise
disp('Будет улучшено в след. версиях')
end
MyS=geroncore(a,b,c);
%[a b c A B C]
Проведем дополнительные вычисления медиан, высот и т.д., в соответствии в 5-м параметром вызова. Обратите внимание, что подфункция может вызывать ранее определенную подфункцию; также – несмотря на краткость определений функций, каждая должна занимать три строки.
%%
% Дополнительные расчеты по пятому параметру:
% med - медианы, bis - биссектрисы, hhh - высоты
MyS=geroncore(a,b,c);
% Объявление новых функций
function res=median(a,b,gamma)
res=COS_opposite(a,0.5*b,gamma);
end
function res=bisectrix(a,b,gamma)
res=2*MyS./((a+b).*sind(gamma/2));
end
function res=height(c)
res=2*MyS./c;
end
% Расчет линий
for i=1:3, varargout{i}=i; end;
if (nargin==5)
switch varargin{5}
case 'med'
varargout{4}=median(b,a,C);varargout{5}=median(a,b,C);
varargout{6}=median(b,c,A);
case 'bis'
varargout{4}=bisectrix(c,b,A);varargout{5}=bisectrix(c,a,B);
varargout{6}=bisectrix(a,b,C);
case 'hhh'
varargout{4}=height(a);varargout{5}=height(b);
varargout{6}=height(c);
otherwise
;
end
end;
Последняя секция короткая. Список аргументов varargout, как и varargin, - это массив ячеек, поэтому присвоения стоят в {}, а не в привычных (). При выводе графика оси рисуются после построения графика, в противном случае оси будут масштабироваться по данным.
%%
%Вывод результатов
varargout{1}=[a A];varargout{2}=[b B];varargout{3}=[c C];
% Как последний штрих - вывод изображения
if (nargin==5)&&(strcmp(varargin{5},'qrh'))
figure(1);plot([1 a.*cosd(C)+1 b+1 1], [1 a.*sind(C)+1 1 1]);
axis([0 (a+b+c)/2 0 (a+b+c)/2]);
end
Для считывания результата приходится делать вызов программы не слишком красивым, например, [x,y,z,t,u,v,w]=MyTriangle(3,4,5,’abc’,’grh’). Все числа можно было бы расположить компактно в одной переменной-массиве (в качестве результата).
