MATLAB: Unit step function - matlab

For some reason when I try to create a simple unit step function I just receive a straight line. I am pretty sure this is correct, but my graph tells me otherwise. Is there something I am doing wrong?
function mone=myOne(t)
[n,~] = size(t);
mone=zeros(n,1);
for i=1:n,
if (t(i)>0),
mone(i) = 1;
end
end
in the command window I type,
t = [-5:0.01:5]
plot(t, myOne(t))

The error is your line:
[n,~] = size(t);
You only query the first dimension of t, which is 1 following
t = [-5:0.01:5]
size(t)
ans =
1 1001
You can either transpose t
t = [-5:0.01:5].';
size(t)
ans =
1001 1
or you length instead of size.
n = length(t);
Finally, a solution without the loop as proposed by #Dan is much faster.

I can't see anything wrong with the logic behind your function but your implementation is very long winded. In Matlab you can just do this:
function mone=myOne(t)
mone = t > 0;
end
or if you want to get a matrix of numbers and not logicals returned try
function mone=myOne(t)
mone = (t > 0)*1; %// Or if you prefer to cast explicitly:
%// double(t>0)
end
Also to add a shift parameter with default set to zero:
function mone=myOne(t, T)
if nargin < 2
T = 0;
end
mone = (t > T)*1;
end
usage:
t = [-5:0.01:5]
plot(t, myOne(t))
plot(t, myOne(t,3))

Related

Evaluate a vector in a piecewise function

I want to evaluate the vector xdata in a piecewise function like this:
dat=load('k2.txt');
xdata = dat(:,1);
ydata = dat(:,2);
n=length(xdata);
p0=[0.0821 6.6 0.4];
y(p0,xdata)
function y_hat = y(p,t)
P=4.885;
T0 = 134.27426;
omega=2*pi/P;
gamma1=0.3539 ;gamma2=0.2851;
c1=0;c2=gamma1+2*gamma2;c3=0;c4=-gamma2;
c0=1-c1-c2-c3-c4;
z= p(2).*((sin(omega.*(t-T0))).^2+((p(3)/p(2)).*cos(omega.*(t-T0))).^2).^(1/2);
lambda1= 0;
lambda3=p(1).^2;
if ((1-p(1)<z) & (z<1+p(1)))
k1 = acos((1-p(1).^2 + z.^2)./(2*z));
k0 = acos(((p(1)).^2+z.^2-1)./(2.*z.*p(1)));
y_hat = 1-1./pi*(p(1).^2.*k0+k1-sqrt((4*z.^2-(1+z.^2-p(1).^2).^2)/4));
end
if (1+p(1)<=z)
y_hat=1-lambda1;
end
if (z<=1-p(1))
y_hat=1-lambda3;
end
end
The problem is that the code doesn't enter none of the if loops and returns nothing. Maybe the reason is that the function tries to fulfill the conditions for all the vector at once? How should I proceed so that y(p0,xdata) returns something?
By the way, I need this because I have to fit a model to data like this:
[theta] = lsqcurvefit(#y, p0, xdata, ydata);
Your code doesn't work, because when you write something like this:
if [1 3 -1] > 0
%code
end
Then "%code" won't be evaluated because it's checking, if the condition holds for every value in the vector.
Let's say you want to define the Heaviside function and evaluate a vector of it. Then, what you do is using a for loop:
x_vals = [-1 1 5];
heav(x_vals)
function y = heav(x)
y = zeros(size(x));
for i = 1:length(x)
if x(i) >= 0
y(i) = 1;
else
y(i) = 0;
end
end
end

Stopping the output of a for cycle in matlab

I'm facing an issue with this simple Fibonacci number generator program:
function f = fibonr(n)
f(1) = 1;
f(2) = 1;
for i = 3:n
f(i) = f(i-1) + f(i-2);
end
end
If I want to display only the n-th number of the sequence, what adjustments should I make?
function f = fibonr(n)
f = zeros(n,1); %//initialise the output array
f(1,1) = 1;
f(2,1) = 1;
for ii = 3:n
f(ii,1) = f(ii-1,1) + f(ii-2,1);
end
%//create a string with text and variables
str = sprintf('The %d th number in the Fibonacci sequence is %d',n,f(ii,1));
disp(str) %//display your output.
end
first up: don't use i as a variable. Secondly, I switched to using column vectors, since MATLAB processes them faster, as well as I initialised the array, which is way faster (hence the shiny orange wiggles below your f(i)= line).
Call your function:
output = fibonr(10);
The 10 th number in the Fibonacci sequence is 55
If you use e.g. n=20 and still want the 10th argument just call output(10)
if you want the specified output right away you can use nargin. This code will give you all of the sequence if you call fibonr(n), or you can specify a vector to get the fibonacy numbers at said positions. If you are interested in both, your specified output and all the numbers, you can call the function with:
[output, fibnumbers] = fibonr(n,v);
function [output,f] = fibonr(n,v)
f(1) = 1;
f(2) = 1;
for i = 3:n
f(i) = f(i-1) + f(i-2);
end
if nargin() > 1
output = f(v);
else
output = f;
end

Meshgrid and double for-loops does not result in the same matrix, why?

I am trying to evaluate all values the expression f = 2y-exp(z) can take for different values of z and y. Were y and z are two vectors of length M. I am wondering why the two approaches for generating the expression f yields different results.
Using meshgrid:
[Y,Z] = meshgrid(y,z);
argument = 2*Y-exp(Z);
and with double for-loops
argument_new = zeros(M,M);
for i = 1:length(y)
for j = 1:length(z)
argument_new(i,j) = 2*y(i)-exp(z(j));
end
end
Any hints will be highly appreciated!
That's because of the way meshgrid creates 'inverted' directions. I don't find the right words, but here is an example illustrating with your code.You see that if you uncomment option 2 and use argument_new(j,i) instead of argument_new(i,j) both matrices are equal (as obtained with isequal).
clear
clc
M = 20;
y = 1:M;
z = 1:M;
[Y,Z] = meshgrid(y,z);
argument = 2*Y-exp(Z);
argument_new = zeros(M,M);
for i = 1:length(y)
for j = 1:length(z)
%// 1)
argument_new(i,j) = 2*y(i)-exp(z(j));
%// 2)
%// argument_new(j,i) = 2*y(i)-exp(z(j));
end
end
isequal(argument,argument_new) %// Gives 0 for option 1 and 1 for option 2.
Blame that on meshgrid:
MESHGRID is like NDGRID except that the order of the first two input
and output arguments are switched (i.e., [X,Y,Z] = MESHGRID(x,y,z)
produces the same result as [Y,X,Z] = NDGRID(y,x,z)).
Solution: use ndgrid, which doesn't do that switching, and is thus more "natural":
[Y,Z] = ndgrid(y,z);
argument = 2*Y-exp(Z);
Or in your code, after meshgrid, add a transpose operation: argument = argument.';)
They are the same, you should just transpose either one (' in Matlab), or you can replace i by j and vice versa in the for loops

Plotting own function in scilab

Hey i have an issuse with plotting my own function in scilab.
I want to plot the following function
function f = test(n)
if n < 0 then
f(n) = 0;
elseif n <= 1 & n >= 0 then
f(n) = sin((%pi * n)/2);
else
f(n) = 1;
end
endfunction
followed by the the console command
x = [-2:0.1:2];
plot(x, test(x));
i loaded the function and get the following error
!--error 21
Invalid Index.
at line 7 of function lala called by :
plot(x, test(x))
Can you please tell me how i can fix this
So i now did it with a for loop. I don't think it is the best solution but i can't get the other ones running atm...
function f = test(n)
f = zeros(size(n));
t = length(n);
for i = 1:t
if n(i) < 0 then
f(i) = 0;
elseif n(i) <= 1 & n(i) >= 0
f(i) = sin((%pi * n(i)/2));
elseif n(i) > 1 then
f(i) = 1;
end
end
endfunction
I guess i need to find a source about this issue and get used with the features and perks matlab/scilab have to over :)
Thanks for the help tho
The original sin is
function f = test(n)
(...)
f(n) = (...)
(...)
endfunction
f is supposed to be the result of the function. Therefore, f(n) is not "the value that the function test takes on argument n", but "the n-th element of f". Scilab then handles this however it can; on your test case, it tries to access a non-integer index, which results in an error. Your loop solution solves the problem.
Replacing all three f(n) by f in your first formulation makes it into something that works... as long as the argument is a scalar (not an array).
If you want test to be able to accept vector arguments without making a loop, the problem is that n < 0 is a vector of the same size as n. My solution would use logical arrays for indexing each of the three conditions:
function f = test(n)
f = zeros(size(n));
negative = (n<0);//parentheses are optional, but I like them for readability
greater_than_1 = (n>1);
others = ~negative & ~greater_than_1;
f(isnegative)=0;
f(greater_than_1)=1;
f(others) = sin(%pi/2*n(others));
endfunction

matlab parcial equation with 2 intervals

Here is the code I have so far :
function [u]=example222(xrange,trange,uinit,u0bound,uLbound);
n = length(xrange);
m = length(trange);
u = zeros(n,m); %%%
Dx = (xrange(n)-xrange(1))/(n-1);
Dt = (trange(m)-trange(1))/(m-1);
u(:,1)=uinit';
u(1,:)=u0bound;
u(n,:)=uLbound;
gegu=0.08;
alpha=0;
koefa=(-Dt*gegu/(2*Dx));
koefb=(alpha*Dt/(Dx)^2);
u
% first time step
for i = 2:n-1
u(i,2) = u(i,1)+2*koefa*(u(i+1,1)-u(i-1,1))+(koefb/2)*(u(i-1,1)-2*u(i,1)+u(i+1,1))
end;
% subsequent time steps
for j = 2:m-1
for i = 2:n-1
u(i,j+1)=u(i,j-1)+koefa*(u(i+1,j)-u(i-1,j))+koefb*(u(i-1,j)-2*u(i,j)+u(i+1,j))
end;
end;
______________________________________
x = (0:0.1:1);
t = (0:0.8:8) ;
u0=zeros;uL=zeros;
uinit=1-(10*x-1).^2;
[u]=example222(x,t,uinit,u0,uL);
surf(x,t,u,'EdgeColor','black')
Next thing I need to do is to implement an interval for uinit=1-(10*x-1).^2
IF x-0.08*t < 0.2. then => uinit=1-(10*x-1).^2;
else uinit=0;
Can someone help me with that please. I was trying to do it with if clauses and loops and couldn't make it work. Help is greatly appreciated.
There are many ways to define a piecewise function my usual method is as follows:
uinit = zeros(size(x));
I = x<(0.08*t+0.2); %// Find the indices where x<(0.08*t+0.2)
uinit(I) = 1-(10*x(I)-1).^2;
This case is easier than what you may often have since you want all the other values of uinit to be zero. If you had another function in the other region (say x^2) you could also do:
uinit(1-I) = x(1-I).^2;
The operation 1-I gives 0 where I==1 and 1 where I==0, therefore your get the complement of I.