without using conv() command, I want to convolve two signals:
This is the code I write:
syms n k i
f= #(n) 2.*(0<=n<=9);
h(n)=((8/9)^n).*heaviside(n-3);
L = length(f);
M = length(h(n));
out=L+M-1;
y=zeros(1,out);
for i = 1:L
for k = 1:M
y(i+k-1) = y(i+k-1) + h(k)*f;
end
end
However, I get an error:
Unable to perform assignment because value of type 'sym' is not convertible to 'double'.
Error in untitled7 (line 13)
y(i+k-1) = y(i+k-1) + h(k)*f;
Caused by:
Error using symengine
Unable to prove '(0.0 <= 0.0) <= 0.0' literally. Use 'isAlways' to test the statement mathematically.
I cannot find a way to fix it and also I do not know how to plot it at the end because of this. Can you help me in both of these issues please?
example how to convolve without command conv
nstop=20;
n1=[-nstop:1:nstop];
n0=nstop+1 % n1(n0)=0
h=zeros(1,numel(n1));
x1=zeros(1,numel(n1));
h(n0+[3:nstop])=(8/9).^[3:nstop];
x1(n0+[0:9])=2;
X1=flip(hankel(x1),2)
H=repmat(h,numel(n1),1);
conv_x_h=sum(X1.*H,2)';
n2=[0:numel(n1)-1]; % time reference for resulting conv
figure;
stem(n1,x1)
hold on
stem(n1,h);
grid on
legend('x1(n)','h(n)')
figure
stem(n2,conv_x_h)
grid on
title('conv(x1,h)')
Related
Trying to get the integral of some experimentally collected data.
After using the envelope and abs functions I'm using the fit function to get the equation I wish to integrate (unfortunately 'poly' isn't giving a close enough fit to the data):
[yupper,ylower] = envelope(signal,1000,'peak');
dat = abs(yupper);
f = fit(x,dat,'linearinterp');
Then when I try
q = integral(f,3e4,9e4);
I get the error:
Error using integral (line 82) First input argument must be a function
handle.
Error in findenergyfromfitcurve (line 10) q = integral(f,3e4,9e4);
I thought f was a (mathematical) function, don't understand what the error is telling me. When I try using 'poly3' incase it's the linearinterp messing things up I still get that error.
TIA
f is a function but its type is cfit not function handle.
integral() function requires function handle, what you can do
is transform cfit into function handle before taking the
integral
The code is as follows
x = rand(5,1);
dat = rand(5,1);
f = fit(x,dat,'linearinterp');
% Create a new function handle
f = #(x)f(x);
q = integral(f, 3e4,9e4, 'ArrayValued', 1)
2) What does the ... 'Array valued', 1) do as well? It didn't work
till I put that in so it must do something
f is a piecewise function, the following illustration is based on the assumption that f is a 2-piecewise linear function, but it can be used for n-piecewise function as well.
The task for fit() function is finding the parameters :
a
b
c
d
k
In terms of code f looks like
function y = f(x,a,b,c,d,k)
% PIECEWISELINE A line made of two pieces
% that is not continuous.
y = zeros(size(x));
% This example includes a for-loop and if statement
% purely for example purposes.
for i = 1:length(x)
if x(i) < k
y(i) = a.* x(i) + b;
else
y(i) = c.* x(i) + d;
end
end
end
To plot a function handle, just use fplot(f)
Here is the graph for f
To sum up, f probably has more than one expression, that's why I set
'ArrayValued' to true so that integral() function knowns f
has more than one expression, omitting it means f has a single
expression which is not true.
I want to fit a curve to some data. I used a PCHIP interpolation because of getting the best results. Moreover, I want to get the coefficients for the 6 intervals with the ppval-function. But there pops up an error like these:
Error using unmkpp (line 18)
The input array does not seem to describe a pp function.
Error in ppval (line 62)
[b,c,l,k,dd]=unmkpp(pp);
Error in SA (line 8)
v = ppval(p,xdata)
This is my code:
clear all
xdata = [0; 3.5; 6.8; 7.6; 8.2; 30; 34.2];
ydata = [0; 50; 400000; 2000000; 25000000; 100000000;100000000]
xq1 = 0:0.01:35;
p = pchip(xdata,ydata, xq1);
s = spline(xdata,ydata,xq1);
v = ppval(p,xdata)
plot(xdata,ydata,'o',xq1,p,'-',xq1,s,'-.');
legend('Datenpunkte','pchip','spline','Location','SouthEast');
Can you help me?
Best regards
Dominik
pchip has two working modes:
Calculating the piecewise polynomial coefficients: pp = pchip(x,y):
returns a piecewise polynomial structure for use with ppval
Interpolating at specified points: p = pchip(x,y,xq):
is the same as p = ppval(pchip(x,y),xq)
returns a vector of interpolated values p corresponding to the query
points in xq
So, you are using the second mode, which is not suited for use with ppval.
In MATLAB, I wish to define an anonymous function which has a definite sum in it, and another anonymous function in that. Here's a MWE which hopefully describes what I am trying to do:
clear; n=1; syms j; a=0; b=sqrt(0.5);
Finv = #(x) logninv(x,a,b);
fun = #(x) 0.5-symsum(Finv(j*x), j, 1, n+1);
fsolve(fun,0.1)
The error returned is:
Error using symfun>validateArgNames (line 211) Second input must be a
scalar or vector of unique symbolic variables.
Error in symfun (line 45)
y.vars = validateArgNames(inputs);
Error in sym/subsasgn (line 762)
C = symfun(B,[inds{:}]);
Error in logninv (line 60) p(p < 0 | 1 < p) = NaN;
Error in #(x)logninv(x,a,b)
Error in #(x)0.5-symsum(Finv(j*x),j,1,n+1)
Error in fsolve (line 217)
fuser = feval(funfcn{3},x,varargin{:});
Caused by:
Failure in initial user-supplied objective function evaluation. FSOLVE cannot
continue.
For this particular choice of Finv I solved it using eval and feval as follows:
clear; n=1; syms j; a=0; b=sqrt(0.5);
Finv = #(x) logninv(x,a,b);
fun = #(x) 0.5-eval(symsum(feval(symengine,'logninv',j*x,a,b), j, 1, n+1));
fsolve(fun,0.1)
which produces the answer in this special case because Finv=#(x) logninv(x,a,b), but this defeats the point, which is that I want to be able to define Finv as a univariate function of my choice, not necessarily a predefined MuPAD expression like 'logninv'.
Any advice would be most appreciated.
Try to force the second variable (i.e., j) as being a symbolic variable with a scalar (numerical) data type. Note in his code, that is only variable is not being initialized.
clear; n=1; syms j integer; a=0; b=sqrt(0.5);
Alternatively, you can check assumptions on each variable. For example,
assumptions(j)
I am trying to solve a system of two stochastic differential equations using "sde_euler". Here is my code:
function y = stoch_Fx_model(t0,tf,F0,x0)
r=1;
sig=1;
lambda=1;
h=1;
S=1;
f= #(t,Y)[r.*Y(1).*(1-Y(1)) -h.*Y(1).*(1-Y(2))./(Y(1)+S);
lambda.*Y(2).*(1-Y(2)).*(1+sig.*(2.*Y(2)-2.*Y(1)-1))];
g=#(t,Y)[0.5;0.6];
dt=0.001;
t=t0:dt:tf;
Y0=[F0;x0];
opts = sdeset('ConstGFUN','yes','NonNegative','yes');
y = sde_euler(f,g,t,Y0,opts);
y = min(y,1);
plot(t,y(:,1))
end
After specifying the values of t0,tf,x0,F0 I run the code and I am encountering the following error:
Error using sdearguments (line 22)
Input vector TSPAN must have length >= 2. See SDE_EULER.
Error in sde_euler (line 130)
[N,D,tspan,tdir,lt,y0,fout,gout,dgout,dg,h,ConstStep,dataType,NonNegative,...
Error in stoch_Fx_model (line 19)
y = sde_euler(f,g,t,Y0,opts);
I don't understand my mistake. my TSPAN is greater than 2 in length. Here is the source for the toolbox:
https://github.com/horchler/SDETools/blob/master/SDETools/sde_euler.m
Any help please?
thank you!
I've tried this:
linefunca = #(xa,ya) aa*xa + ba*ya + ca;
figure(1)
imshow(Pica);
hold on;
ezplot(linefunca,[1,1072,1,712]);
But I'm returned with this error:
In an assignment A(I) = B, the number of elements in B and I must be the same.
Error in ezplotfeval/applyfun (line 80)
z(i) = feval(f,x(i),y(i));
Error in ezplotfeval (line 65)
z = applyfun(x,y);
Error in ezplot>ezimplicit (line 257)
u = ezplotfeval(f, X, Y);
Error in ezplot (line 153)
hp = ezimplicit(cax, f{1}, vars, labels, args{:});
Error in ps3 (line 313)
ezplot(linefunca,[1,1072,1,712]);
aa,ba,ca are all known values (column vectors). The x and y limits are the size of the image that I'm working with. I'm trying to plot a set of epipolar lines. Any suggestions?
EDIT:
lt = length(aa);
linefunca = #(x,y,t) aa.*x(t) + ba.*y(t) + ca(t);
figure(1)
imshow(Pica);
hold on;
for t=1:lt
ezplot(#(x,y,t) linefunca(x,y,t),[1,lt]);
end
As far as I know, ezplot can not plot a series of lines like plot. A way to work around this would be to add a parameter k to the anonymous function, which is used to select the current line. You can then go through all lines in a for loop and plot them one-by-one.
Further: as it is stated on the ezplot help page, you have to use the array functions .*, ./ and .^ , so ezplot can use vectors to evaluate the function.
N = 5;
aa = rand(N,1); ba = rand(N,1); ca = rand(N,1);
linefunca = #(xa,ya,k) aa(k).*xa + ba(k).*ya + ca(k);
hold on
for k=1:N
ezplot(#(x,y)linefunca(x,y,k),[-5,5,-5,5]);
end
hold off