Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
matlab72_core.doc
Скачиваний:
4
Добавлен:
01.07.2025
Размер:
2 Мб
Скачать
☆

Пример:

  1. Построить и оформить графики трех функций , 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 в консоли) см. на рис. снизу и слева.

  1. Записать в виде м-функции вычисления по формуле Герона в файле 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

  1. Записать в виде м-функции 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’). Все числа можно было бы расположить компактно в одной переменной-массиве (в качестве результата).