2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 график кусочной функции в matlab
Сообщение19.03.2017, 15:39 
приветствую)помогите реализовать данную программу в matlab.

построить график сложной функции

$Y(t)=5-5\exp(-0.1t) $ , t<20
$Y(t)=\exp(-0.1t) $ , 20<t<35
$Y(t)=10-10\exp(-0.05t)$ , t>45

используя цикл for на промежутке [0;50] с шагом 0,5

 
 
 
 Re: график кусочной функции в matlab
Сообщение19.03.2017, 16:50 
Для построения графика кусочно-заданной функции в Matlab есть две возможности.
I. Можно в цикле for вычислить значения аргумента x и соответствующие значения функции.
II. Можно воспользоваться тем, что в matlab определено умножение логического значения на число с плавающей точкой. Обозначим логическое через b, а с плавающей точкой через d. Если логическое имеет значение True, то результат b*d число d. Если логическое имеет значение False, то результат 0.

Пусть надо построить график функции на промежутке $(-1.5, 1.5)$ c шагом 0.05
$y= \begin {cases} -1, & x < -1;\\ \, x, & -1 \le x \le 1; \\ 1, & x > 1.\end {cases}$

I. Сначала зададим массивы и сохраним в N их длину. Затем вычислим в цикле значения Y. За циклом воспользуемся функцией plot для построения графика.
Используется синтаксис Matlab M
X = [-1.5:0.05:1.5];
N = length(X);
Y = zeros(1,N);
for i = 1:N
  if X(i) < -1
   Y(i) = -1;
  elseif X(i) <= 1
   Y(i) = X(i);
  else
   Y(i) = 1;
  end
end
plot(X, Y)

II. Зададим для удобства inline-функцию. (inline устарела, и не будет со временем поддерживаться. В новых версиях рекомендуется вместо inline использовать анонимные функции.)
Используется синтаксис Matlab M
f = inline('(x<-1).*(-1)+ and(x >=-1, x <=1).*x+(x>1).*1');
X = [-1.5:0.05:1.5];
Y = f(X);
plot(X, Y);

Синтаксис цикла for, условной конструкции if и нужных функций (например, plot) подробно изложен в учебниках и Сети. В чем проблемы?

-- Вс 19.03.2017 16:02:38 --

Наконец, можно воспользоваться условной индексацией.
Используется синтаксис Matlab M
X = [-1.5:0.05:1.5]
Y(X<-1) = -1;
Ind = and(-1 <=X, X <=1);
Y(Ind) = X(Ind);
Y(X > 1) = 1;
plot(X, Y)
Условная индексация и «векторная парадигма» Matlab позволяют во многих случаях не использовать «универсальные управляющие структуры» (for, if, while).

 
 
 
 Re: график кусочной функции в matlab
Сообщение19.03.2017, 17:31 
Спасибо за подсказку. Решал первым методом. Для чего нужна эта строка
Y = zeros(1,N);?
Программа работает и без неё.

 
 
 
 Re: график кусочной функции в matlab
Сообщение19.03.2017, 17:40 
Это строка нужна, чтобы в цикле не изменялся размер массива. Можно избежать изменения размера массива в цикле, если первым присвоением будет присвоение элементу с максимальным индексом.
Используется синтаксис Matlab M
X = [-1.5:0.05:1.5];
N = length(X);
for i = N:-1:1
  if X(i) < -1
   Y(i) = -1;
  elseif X(i) <= 1
   Y(i) = X(i);
  else
   Y(i) = 1;
  end
end
plot(X, Y)

 
 
 
 Re: график кусочной функции в matlab
Сообщение19.03.2017, 18:26 
А в матлабе нет команды задать функцию кусочно? В мейпле и математике для этого есть Piecewise.

 
 
 
 Re: график кусочной функции в matlab
Сообщение19.03.2017, 18:43 
В старых версиях piecewise не было, например в 6.5. Историю не отслеживал, но как минимум с 2013 (может и раньше, не следил) ...
Поддержка символьных вычислений в старых версиях matlab основана на Maple. В новых версиях — на MuPAD. Насколько я смог разобраться, и в старых, и в достаточно новых версиях полноценной поддержки символьной piecewise нет. В следующих двух сообщениях приведен вариант использования piecewise для старых и новых версий соответственно. Но в таком варианте это ничего не дает по сравнению с описанным выше вариантом II. (Но в варианте II текст и короче, и более естественный для matlab.) Будем надеяться, найдутся знатоки, которые приведут более осмысленные варианты. На мой же взгляд, на данный момент ситуация в символьном движке такая, что при необходимости использования символьного объекта piecewise разумней перейти в одну из СКА (Maple, Mathematica, MuPAD,…).

 
 
 
 Re: график кусочной функции в matlab
Сообщение19.03.2017, 21:08 
Очень криво для старых версий (проверялось в 6.5) у меня на скорую руку получилось так.
1. Создаю в Maple функцию и записываю в текстовый файл c именем f.src (в приводимом ниже примере он лежит в текущей директории.)
Код:
f:= proc(x)
  piecewise(x < -1, -1, x <=1, x, x > 1 , 1 ):
end:

2. Стандартным образом загружаю исходник функции в Matlab (например, в командном окне)
>> procread('f.src');

3. Если хочу обрабатывать массив, то пишу функцию (она без проверок, чтобы не загромождать код), которая будет в цикле вызывать f и передавать скалярный символьный аргумент. Если хочу получать результат в виде double array, то символьный результат преобразую при помощи конструктора double (использую как функцию преобразования)
Используется синтаксис Matlab M
function Y = ff(X)
 Y = zeros(1, length(X));
 for i=1:length(X)
  Y(i) = double(maple('f', sym(X(i))));
 end;    
end;

Теперь, например в командном окне, задаю X, вычисляю Y и строю график
>> X = [-1.5:0.05:1.5];
>> Y = ff(X);
>> plot(X, Y)


Upd2. Конечно, держать исходник такой простой функции в файле на диске нет особого смысла. Вместо сохранения исходника на диске и загрузки его в Matlab можно было в командном окне ввести
>> r = maple('f:= proc(x) piecewise(x < -1, -1, x <=1, x, x > 1 , 1 ): end')
Или вставить эту строчку в m-функцию ff.

 
 
 
 Re: график кусочной функции в matlab
Сообщение20.03.2017, 20:42 
Piecewise в новых версиях (MuPAD), например, в R2013

В стиле близком к стилю предыдущего сообщения. m-функция нужна для обработки векторного аргумента.
Но в ней же ниже определяется и сама функция MuPAD: r = evalin(symengine, 'f := x -> piecewise([x<-1, -1], [x>1, 1], [Otherwise, x]):');
Используется синтаксис Matlab M
function Y = pw(X)
r = evalin(symengine, 'f := x -> piecewise([x<-1, -1], [x>1, 1], [Otherwise, x]):');
 Y = zeros(1, length(X));
  for i=1:length(X)
   Y(i) = double(feval(symengine,'f', X(i)));
 end    
end
В качестве теста строим график в командном окне
>> X = [-1.5:0.05:1.5];
>> Y = pw(X);
>> plot(X, Y)

 
 
 
 Re: график кусочной функции в matlab
Сообщение25.03.2017, 13:54 
GAA в сообщении #1201808 писал(а):
Используется синтаксис Matlab M
f = inline('(x<-1).*(-1)+ and(x >=-1, x <=1).*x+(x>1).*1');

Зачем inline, когда просто
Используется синтаксис Matlab M
y=(x<-1).*(x<1) + (x >=-1).*(x <=1).*x + (x>1).*1;
?

 
 
 
 Re: график кусочной функции в matlab
Сообщение25.03.2017, 18:24 
ewert, просто тупо скопировал. В исходном тексте было многократное использование выражения, поэтому оно [это выражение] было оформлено в виде функции. На работе был занят и сразу не перечитал текст. Потом увидел, но не стал исправлять: думал и так очевидно.
Но, конечно, на форуме надо быть аккуратней. Спасибо, ewert, за замечание.

-- Сб 25.03.2017 17:35:05 --

Вот с piecewise я не в курсе. Это интересно.

 
 
 [ Сообщений: 10 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group