MATLAB分段函数 [英] MATLAB Piecewise function
问题描述
我必须在MATLAB中构造以下函数,并且遇到了麻烦.
I have to construct the following function in MATLAB and am having trouble.
考虑在[0,4)中为t定义的函数s(t),
Consider the function s(t) defined for t in [0,4) by
{ sin(pi*t/2) , for t in [0,1)
s(t) = { -(t-2)^3 , for t in [1,3)*
{ sin(pi*t/2) , for t in [3,4)
(i)生成由512个均值组成的列向量 在[0,4)间隔内此函数的样本. (这 最好通过串联三个向量来完成.)
(i) Generate a column vector s consisting of 512 uniform samples of this function over the interval [0,4). (This is best done by concatenating three vectors.)
我知道它一定是某种形式.
I know it has to be something of the form.
N = 512;
s = sin(5 * t/N)." ;
N = 512;
s = sin(5*t/N).' ;
但是我需要s为分段函数,有人可以为此提供帮助吗?
But I need s to be the piecewise function, can someone provide assistance with this?
推荐答案
如果我理解正确,那么您正在尝试创建3个向量来计算所有t
的特定函数输出,然后对每个向量进行切片并将它们连接起来取决于t
的实际值.这是低效的,因为您初始化的向量是您实际想要的3倍(内存),并且进行的计算是CPU的3倍,而其中大部分将被丢弃.最重要的是,如果您的t
并非您期望的 (即单调递增),则使用级联会有些棘手.这可能是不太可能的情况,但总的来说更好.
If I understand correctly, you're trying to create 3 vectors which calculate the specific function outputs for all t
, then take slices of each and concatenate them depending on the actual value of t
. This is inefficient as you're initialising 3 times as many vectors as you actually want (memory), and also making 3 times as many calculations (CPU), most of which will just be thrown away. To top it off, it'll be a bit tricky to use concatenate if your t
is ever not as you expect (i.e. monotonically increasing). It might be an unlikely situation, but better to be general.
这里有两个选择,第一个是imho不错的Matlab方法,第二个是更常规的方法(如果您来自C ++或类似的东西,您可能会更习惯了,我使用了很长时间).
Here are two alternatives, the first is imho the nice Matlab way, the second is the more conventional way (you might be more used to that if you're coming from C++ or something, I was for a long time).
function example()
t = linspace(0,4,513); % generate your time-trajectory
t = t(1:end-1); % exclude final value which is 4
tic
traj1 = myFunc(t);
toc
tic
traj2 = classicStyle(t);
toc
end
function trajectory = myFunc(t)
trajectory = zeros(size(t)); % since you know the size of your output, generate it at the beginning. More efficient than dynamically growing this.
% you could put an assert for t>0 and t<3, otherwise you could end up with 0s wherever t is outside your expected range
% find the indices for each piecewise segment you care about
idx1 = find(t<1);
idx2 = find(t>=1 & t<3);
idx3 = find(t>=3 & t<4);
% now calculate each entry apprioriately
trajectory(idx1) = sin(pi.*t(idx1)./2);
trajectory(idx2) = -(t(idx2)-2).^3;
trajectory(idx3) = sin(pi.*t(idx3)./2);
end
function trajectory = classicStyle(t)
trajectory = zeros(size(t));
% conventional way: loop over each t, and differentiate with if-else
% works, but a lot more code and ugly
for i=1:numel(t)
if t(i)<1
trajectory(i) = sin(pi*t(i)/2);
elseif t(i)>=1 & t(i)<3
trajectory(i) = -(t(i)-2)^3;
elseif t(i)>=3 & t(i)<4
trajectory(i) = sin(pi*t(i)/2);
else
error('t is beyond bounds!')
end
end
end
请注意,当我尝试使用常规方式"时,有时对于您正在处理的采样大小而言会更快,尽管第一种方式(myFunc
)确实会更快,因为您实际进行了很多扩展.无论如何,我建议采用第一种方法,因为它更易于阅读.
Note that when I tried it, the 'conventional way' is sometimes faster for the sampling size you're working on, although the first way (myFunc
) is definitely faster as you scale up really a lot. In anycase I recommend the first approach, as it is much easier to read.
这篇关于MATLAB分段函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!