I am attempting to minimize this nonlinear function
using the BFGS optimization method in MATLAB. However, I am having a terrible time figuring out how to code the function for n=500. I have tried these variations with no luck:
1)
S_symsum = #(x) (100*(x(2*(1:250))-x(2*(1:250)-1)^2)^2+(1-x(2*(1:250)-1))^2);
2)
k = 1:N/2;
V = (100*(x(2*k)-x(2*k-1).^2).^2+(1-x(2*k-1)).^2);
f = sum(V);
3)f = symsum(100*(x(2*k)-x(2*k-1).^2).^2+(1-x(2*k-1)).^2,k,1,500)
EDIT: As the BFGS method necessitates, I will need to be able to take the gradient of the function f at each iterate. So, the function formulation will need to hold this property
I use N = 10 for illustration, just change it to 500 for your optimization.
% given length of x, here N
N = 10;
% supposed x is a row vector
x = sym('x', [1,N]);
f = 0;
for i = 1:N/2
f = f + 100.*(x(2*i) - (x(2*i-1)).^2) + (1-x(2*i-1)).^2;
end
% gradient
% to compute gradient, use syms function type
g = gradient(f);
% for evaluating the function or the gradient use function handle
feval = matlabFunction(f, 'vars', {x});
geval = matlabFunction(g, 'vars', {x});
Related
I am trying to plot and then to use it with Matlab
in an ODE as coefficient, the function
f : [2,500] -> [0,1],
But I don't know how to write the code for the definition of the function, since it is given on different subintervals.
Below is an example that uses anonymous functions/function handles. It uses each region/condition and evaluates the boundaries numerically and stores them into variables Bounds_1 and Bounds_2. These boundaries are then used to truncate each signal by multiplying each section of the piecewise function by its corresponding condition which is a logical array. It's also good to note that this plot will almost be seen as an impulse since the bounds are really small. Alternatively, you can probably achieve the same results using the built-in piecewise() function but I think this method gives a little more insight. As i increases you'll see a plot that resembles more and more of an impulse. To plot this for multiple values or i this can be run in a for-loop.
clc;
i = 3;
Bounds_1 = [i - (1/i^2),i];
Bounds_2 = [i,i + (1/i^2)];
Bounds = [Bounds_1 Bounds_2];
Min = min(Bounds);
Max = max(Bounds);
f1 = #(x) (i^2.*x - i^3 + 1).*(Bounds_1(1) < x & x <= Bounds_1(2));
f2 = #(x) (-i^2.*x + i^3 + 1).*(Bounds_2(1) < x & x <= Bounds_2(2));
f = #(x) f1(x) + f2(x);
fplot(f);
xlim([Min-2 Max+2]);
ylim([0 1.1]);
Here is another solution. You can specify the steps along the x-axis withxstep. With xlower and xupper you can specify the range of the x-axis:
figure ; hold on;
xlabel('x'); ylabel('f(x)');
for i= 2:500
[f,x] = myfunction(0.5,i);
plot (x,f,'DisplayName',sprintf('%i',i));
end
% legend
function [f,x]=myfunction(xstep,i)
%xstep: specifies steps for the x values
% specify max range x \in = [xlower -> xupper]
xlower = -10;
xupper = 600;
x2 = (i-1/i^2): xstep: i;
f2 = i^2*x2 - i^3 + 1;
x3 = i+xstep:xstep:(1+1/i^2);
f3 = -i^2*x3 + i^3 +1;
x1 = xlower:xstep:(i-1/i^2);
f1 = 0*x1;
x4 = (i+1/i^2):xstep:xupper;
f4 = 0*x4;
f = [f1,f2,f3,f4];
x = [x1,x2,x3,x4];
end
Here is what I get
Besides, I am not exactly sure what you mean with ODE (ordinary differential equation) in f(x). For me it seems like an algebraic equation.
The C code that finds the following integral according to the Simpson's 1-3 (h / 3) method is given below. Fill in the blanks on the code appropriately.
I want to solve this question below in Matlab but i didn't do it. This is simple question but i can't do it. If someone will help me, i will be very happy.
C code version
[C code version2
I tried this code block in Matlab:
% Ask for user input
% Lower bound (a)
a = input('What is your lower bound (a)?')
% Upper bound (b)
b = input('What is your upper bound (b)?')
% Subintervals
N = input('How many subintervals (N)?')
% Defining function
f = #(x,e) (e*x+sin(x))
% Finding h
h=(b-a)/N;
% Finding the values of x for each interval
x=linspace(a,b,N);
% Calculating the integral
for i = 1:N-1
I(i)= (h/3)*(f(x(i))+(4*f((x(i)+x(i+1))/2))+f(x(i+1)));
end
answer1 = sum(I)
disp(I)
% adding f(b) to sum
val2=ff(length(xx));
sum=val1+val2+sum;% set sum
% set result
result=sum*h/3;
Note that MATLAB does not use the symbol e as Neperian Number (Euler's number). To produce Euler's number in MATLAB, you can use exponential function exp(x), e = exp(1),
Therefore, First, correct your function definition:
F = #(x) exp(1).^x + sin(x) % Always try to use Upper-Case letters for your variable/function name
Then, you can use the following snippet to calculate the Integral using Simpson's 1/3:
a = 0; b = 3; N = 1e4;
F = #(x) exp(1).^x + sin(x);
h = ((b-a)/2)/N;
x = linspace(a,b,N);
I = 0;
for i = 1:N-1
I = I + h/3*(F(x(i)) + 4*F((x(i)+x(i+1))/2) + F(x(i+1)));
end
disp(I)
% To compare your result:
Itz = trapz(x, F(x))
The documentation online for this particular function is poor, and I was looking for an example on how to use it. It seems to take in 9+ arguments, but I'm not entirely sure what they even are. I am working on implementing function using the trapezoidal rule, however, I am missing the functions that compute the partial derivatives with respect to y and t. I believe that calculating one for t in MATLAB is another case, but here, I'm just trying to use MATLAB to compute it for y.
I'm using the following input initially:
func = #(t,y)(y.^2+y+t);
interval = [0 1];
y0 = 0;
[steps, derivY, derivJ, W, inverseW] = getTrapezoidalODEValues(func, interval, y0)
I set up the function like this:
function [h,J,T,W,iW] = getTrapezoidalODEValues(odefun,tspan,y0,options)
if (nargin==3)
options = odeset();
end
h = NaN; J(0) = NaN; T(0) = NaN; W(0) = NaN; iW = NaN;
[t,yy] = ode(odefun,tspan,y0,options);
[nstep,ndim] = size(yy);
d = 1/(2+sqrt(2));
for j=2:nsteps
h = t(j)-t(j-1);
I = eye(???,???); % identity matrix
quadpoly = ???; % the quadratic polynomial
J(j-1) = numjac(???); % <--partial derivative of odefun with respect to y
T(j-1) = ???; % partial derivative of odefun with respect to t
W(j-1) = I - h .* d .* J;
iW(j-1) = inv(W(j-1));
end
end
I am trying to implement the Taylor method for ODEs in MatLab:
My code (so far) looks like this...
function [x,y] = TaylorEDO(f, a, b, n, y0)
% syms t
% x = sym('x(t)'); % x(t)
% f = (t^2)*x+x*(1-x);
h = (b - a)/n;
fprime = diff(f);
f2prime = diff(fprime);
y(0) = y0,
for i=1:n
T((i-1)*h, y(i-1), n) = double(f((i-1)*h, y(i-1)))+(h/2)*fprime((i-1)*h, y(i-1))
y(i+1) = w(i) + h*T(t(i), y(i), n);
I was trying to use symbolic variables, but I donĀ“t know if/when I have to use double.
I also tried this other code, which is from a Matlab function, but I do not understand how f should enter the code and how this df is calculated.
http://www.mathworks.com/matlabcentral/fileexchange/2181-numerical-methods-using-matlab-2e/content/edition2/matlab/chap_9/taylor.m
As error using the function from this link, I got:
>> taylor('f',0,2,0,20)
Error using feval
Undefined function 'df' for input arguments of type 'double'.
Error in TaylorEDO (line 28)
D = feval('df',tj,yj)
The f I used here was
syms t
x = sym('x(t)'); % x(t)
f = (t^2)*x+x*(1-x);
This is a numerical method, so it needs numerical functions. However, some of them are computed from the derivatives of the function f. For that, you need symbolic differentiation.
Relevant Matlab commands are symfun (create a symbolic function) and matlabFunction (convert a symbolic function to numerical).
The code you have so far doesn't seem salvageable. You need to start somewhere closer to basics, e.g., "Matlab indices begin at 1". So I'll fill the gap (computation of df) in the code you linked to. The comments should explain what is going on.
function [T,Y] = taylor(f,a,b,ya,m)
syms t y
dfs(1) = symfun(f, [t y]); % make sure that the function has 2 arguments, even if the user passes in something like 2*y
for k=1:3
dfs(k+1) = diff(dfs(k),t)+f*diff(dfs(k),y); % the idea of Taylor method: calculate the higher derivatives of solution from the ODE
end
df = matlabFunction(symfun(dfs,[t y])); % convert to numerical function; again, make sure it has two variables
h = (b - a)/m; % the rest is unchanged except one line
T = zeros(1,m+1);
Y = zeros(1,m+1);
T(1) = a;
Y(1) = ya;
for j=1:m
tj = T(j);
yj = Y(j);
D = df(tj,yj); % syntax change here; feval is unnecessary with the above approach to df
Y(j+1) = yj + h*(D(1)+h*(D(2)/2+h*(D(3)/6+h*D(4)/24)));
T(j+1) = a + h*j;
end
end
Example of usage:
syms t y
[T, Y] = taylor(t*y, 0, 1, 2, 100);
plot(T,Y)
% Code slightly modified from Signals and Systems by Lathi MS2P4 pg 232.
How can I make this code a function? So that I can just "call" it to use it. Instead of pasting this whole thing over and over. This is just a convolution animation of two functions.
figure(1) % Create figure window and make visible on screen
x = #(t) cos(2*pi*3*t).* u(t);
h = #(t) u(t)-u(t-1);
dtau = 0.005;
tau = -1:dtau:4;
ti = 0;
tvec = -1:0.1:5;
y = NaN*zeros(1,length(tvec)); % Pre-allocate memory
for t = tvec,
ti = ti + 1; % Time index
xh = x(t-tau).*h(tau);
lxh = length(xh);
y(ti) = sum(xh.*dtau); % Trapezoidal approximation of integral
subplot(2,1,1)
plot(tau,h(tau),'k-',tau,x(t-tau),'k--',t,0,'ok')
axis([tau(1) tau(end) -2.0 2.5])
patch([tau(1:end-1);tau(1:end-1);tau(2:end);tau(2:end)],...
[zeros(1,lxh-1);xh(1:end-1);xh(2:end);zeros(1,lxh-1)],...
[0.8 0.8 0.8],'edgecolor','none')
xlabel('\tau')
legend('h(\tau)','x(t-\tau)','t','h(\tau)x(t-\tau)')
c = get(gca,'children');
set(gca,'children',[c(2);c(3);c(4);c(1)]);
subplot(2,1,2)
plot(tvec,y,'k',tvec(ti),y(ti),'ok')
xlabel('t')
ylabel('y(t) = \int h(\tau)x(t-\tau) d\tau')
axis([tau(1) tau(end) -1.0 2.0])
grid
drawnow
% pause
end
You can use Matlab's function , as described here
So, you have to write on the top "function yourFunctionName" and then you can call it using its name, yourFunctionName in this case.
Here is what worked with your exact code, a straightforward function definition and the addition of u(t) that was missing from the OP:
figure(1) % figure window outside function
u = #(t)heaviside(t); % define step function
x = #(t) cos(2*pi*3*t).* u(t);
h = #(t) u(t)-u(t-1);
dtau = 0.005;
convol_anime(x, h, dtau); % pass function handles + parameters
where you have already defined:
function convol_anime(x, h, dtau)
tau = -1:dtau:4; ti = 0; tvec = -1:0.1:5;
y = nan*zeros(1,length(tvec));
...