Find the optimum combination - matlab

I am trying to optimise this: function [ LPS, LCE ] = runProject( Nw, Np, Nb) which calls some other functions I have written before. The idea is to find the optimum combination of Nw, Np, Nb AND keep the LPS=0, while LCE is minimum. Nw, Np, Nb should be positive integers. LCE will also be positive.
function [ LPS, LCE ] = runProject( Nw, Np, Nb)
%
% Detailed explanation goes here
[Pg, Pw, Pp] = Pgener();
[Pb, LPS] = Bat( Pg );
[LCE] = Constr(Pw, Pp, Nb)
end
However, I tried the gamultiobj solver from the Global Optimization Toolbox of matlab2015 (trial version) for a different approach with pareto front, but I got the error:
"Optimization running.
Error running optimization.
Not enough input arguments."

You should write your objective function like the following example:
function scores = rastriginsfcn(pop)
%RASTRIGINSFCN Compute the "Rastrigin" function.
% pop = max(-5.12,min(5.12,pop));
scores = 10.0 * size(pop,2) + sum(pop .^2 - 10.0 * cos(2 * pi .* pop),2);
As you can see, the function accepts all the inputs as a single vector pop.
With such representation I can evaluate the function as follows:
rastriginsfcn([2 3])
>> ans
13
Still for running the optimization from the toolbox you have to mention the number of variables, for instance, in my example it is equal to 2:
[x fval exitflag] = ga(#rastriginsfcn, 2)
It is the same for the multi-objective optimization. Check the following image from MATHWORKS:

Related

Solving system of equations on MATLAB, when a constant exists in variable matrix?

How do I solve the following system of equations on MATLAB when one of the elements of the variable vector is a constant? Please do give the code if possible.
More generally, if the solution is to use symbolic math, how will I go about generating large number of variables, say 12 (rather than just two) even before solving them?
For example, create a number of symbolic variables using syms, and then make the system of equations like below.
syms a1 a2
A = [matrix]
x = [1;a1;a2];
y = [1;0;0];
eqs = A*x == y
sol = solve(eqs,[a1, a2])
sol.a1
sol.a2
In case you have a system with many variables, you could define all the symbols using syms, and solve it like above.
You could also perform a parameter optimization with fminsearch. First you have to define a cost function, in a separate function file, in this example called cost_fcn.m.
function J = cost_fcn(p)
% make sure p is a vector
p = reshape(p, [length(p) 1]);
% system of equations, can be linear or nonlinear
A = magic(12); % your system, I took some arbitrary matrix
sol = A*p;
% the goal of the system of equations to reach, can be zero, or some other
% vector
goal = zeros(12,1);
% calculate the error
error = goal - sol;
% Use a cost criterion, e.g. sum of squares
J = sum(error.^2);
end
This cost function will contain your system of equations, and goal solution. This can be any kind of system. The vector p will contain the parameters that are being estimated, which will be optimized, starting from some initial guess. To do the optimization, you will have to create a script:
% initial guess, can be zeros, or some other starting point
p0 = zeros(12,1);
% do the parameter optimization
p = fminsearch(#cost_fcn, p0);
In this case p0 is the initial guess, which you provide to fminsearch. Then the values of this initial guess will be incremented, until a minimum to the cost function is found. When the parameter optimization is finished, p will contain the parameters that will result in the lowest error for your system of equations. It is however possible that this is a local minimum, if there is no exact solution to the problem.
Your system is over-constrained, meaning you have more equations than unknown, so you can't solve it. What you can do is find a least square solution, using mldivide. First re-arrange your equations so that you have all the constant terms on the right side of the equal sign, then use mldivide:
>> A = [0.0297 -1.7796; 2.2749 0.0297; 0.0297 2.2749]
A =
0.029700 -1.779600
2.274900 0.029700
0.029700 2.274900
>> b = [1-2.2749; -0.0297; 1.7796]
b =
-1.274900
-0.029700
1.779600
>> A\b
ans =
-0.022191
0.757299

Is there a higher-order version of cumtrapz()?

Introduction
Suppose I have N points x(1:N) at which I have function values f(1:N), for example:
x = [ 0.0795, 0.1327, 0.1395, 0.5133, 0.6470, 0.7358, 0.7640 ];
f = [ 0.0388, 0.4774, 0.4547, 0.0784, 0.3241, 0.2818, 0.9667 ];
I want to calculate the cumulative integral of f with respect to x using these data.
Low-Order Solution
In MATLAB, I can do this easily using cumtrapz():
>> result = cumtrapz( x, f )
result =
0 0.0137 0.0169 0.1165 0.1434 0.1703 0.1879
Problem
Unfortunately, cumtrapz() uses the trapezoidal method for numerical integration, which is insufficient for my purposes.
Higher-order methods exist, like Simpson's Rule, but to my knowledge there isn't a function that performs the cumulative version of Simpson's Rule for nonuniform grids at the MATLAB File Exchange, or anywhere else.
Does a higher-order version of cumtrapz() already exist? If not, what would I have to do to implement it myself?
I don't know of another method however you could use an interpolation with a pchip, spline, or some other method to increase the resolution. Then use cumtrapz to get a closer approximation of the numeric integral.
It would be up to you to determine what method is applicable to your function.
Example using a sine function and spline
>> x = linspace(0,pi,5);
>> f = sin(x);
>> intF = cumtrapz(x,f);
error = 2-intF(end)
error =
0.1039
>> x2 = linspace(x(1),x(end),numel(x)*10); %Up sample by 10x
>> f2 = interp1(x,f,x2,'spline'); %Interpolate with spline
>> intF2 = cumtrapz(x2,f2);
>> error = 2-intF2(end) %MUCH LESS ERROR
error =
-0.0038

How can I get MATLAB to display radians in terms of pi?

I am trying to make a programme to convert cartesian coordinates to polar coordinates.
My calculator returns arctan(1) as pi/4.
MATLAB on the other hand returns atan(1) as 0.7854.
How can I get MATLAB to return numbers like this as expressions of pi?
As you've stated this is just for a quick visual check, I would just divide by pi:
n = 0.7854;
disp(['n in terms of pi: ', num2str(n/pi), '*pi']);
>> n in terms of pi: 0.25*pi
If this was something you wanted to often do, I would define some function on your local path like so
function [val, str] = wrtpi(n)
% Returns the value of n with respect to pi
val = n/pi;
% Could include some rounding checks here if you wanted to complicate things
% ... *checks* ...
str = ['n in terms of pi: ', num2str(n/pi), '*pi'];
end
Then
n = 0.7854;
[val, str] = wrtpi(n)
>> val = 0.25
str = n in terms of pi: 0.25*pi
You also say this is just for identifying radian quadrants, aside from learning them, you could also just have a simple function
function q = quadrant(n)
Qs = pi*[0, 1/2, 1, 3/2]; % Quadrants
q = find(Qs <= mod(n,2*pi), 1, 'last'); % Index within the quadrants
% You could make this accept vector inputs using:
% q = arrayfun(#(x) find(Qs <= mod(x,2*pi), 1, 'last'), n)
end
Then
quadrant(2*pi - 0.0001) % >> 4
quadrant(0.2) % >> 1
quadrant(1.6) % >> 2
Note that using the symbolic math toolbox for something as simple as this will likely cause more complications and slowdown than it helps!
For some particular values of pi you can use symbolic numbers, for example:
atan(sym(1))
ans =
pi/4
asin(sym(3^.5/2))
ans =
pi/3
Note that this requires the Symbolic Math Toolbox.

Having errors with userdefined functions

Doing homework and there's a question that's giving me trouble. The questions is:
a)create a function M-file called nmoles that requires two vector inputs—
the mass and molecular weight—and returns the corresponding number
of moles. Because you are providing vector input, it will be necessary
to use the meshgrid function in your calculations.
b) Test your function for the compounds shown in the following table, for
masses from 1 to 10 g:
In my function file, i've got:
function [ n ] = nmoles(m, MW)
%% Finds number of moles
m = (1:10); %% mass range
MW = [78.115 46.07 102.3]; %% Values from the table
n=m/MW; %%formula provided by the textbook
My main file only has:
nmoles(m,MW)
I'm getting an error: "Error using / Matrix dimensions must agree"
Also: Error in nmoles (line 10) n=m/MW;
I'm inexperienced with MATLAB and still learning syntax but I assume that my formula is incorrect and i'm using the wrong symbol to divide, though i'm not sure how to correct this. Also, how would i incorporate the meshgrid function into my anwser?
Here is how your function should probably look like:
function [ n ] = nmoles(m, MW)
% Finds number of moles
[mv,MWv] = meshgrid(m, MW); % extends m and MW to match all combinations.
n = mv./MWv; %formula provided by the textbook
end
And then your main script should be:
m = 1:10; % mass range
MW = [78.115 46.07 102.3]; % Values from the table
nmoles(m, MW)
You had 3 mistakes:
If you get m and MW as input to the function, your not suppose to define them within it.
Because you want the number of moles for each combination of mass and molar weight, you use meshgrid.
When you want to perform an elementwise division or multiplication on 2 arrays, put a . before the / or *. In MATLAB everything is a matrix by default, and so this operations are interpreted as matrix multiplication and division by default. If you want to do a regular division or multiplication you use .* and ./. This is true also for power (^ and .^).

Implementing iterative solution of integral equation in Matlab

We have an equation similar to the Fredholm integral equation of second kind.
To solve this equation we have been given an iterative solution that is guaranteed to converge for our specific equation. Now our only problem consists in implementing this iterative prodedure in MATLAB.
For now, the problematic part of our code looks like this:
function delta = delta(x,a,P,H,E,c,c0,w)
delt = #(x)delta_a(x,a,P,H,E,c0,w);
for i=1:500
delt = #(x)delt(x) - 1/E.*integral(#(xi)((c(1)-c(2)*delt(xi))*ms(xi,x,a,P,H,w)),0,a-0.001);
end
delta=delt;
end
delta_a is a function of x, and represent the initial value of the iteration. ms is a function of x and xi.
As you might see we want delt to depend on both x (before the integral) and xi (inside of the integral) in the iteration. Unfortunately this way of writing the code (with the function handle) does not give us a numerical value, as we wish. We can't either write delt as two different functions, one of x and one of xi, since xi is not defined (until integral defines it). So, how can we make sure that delt depends on xi inside of the integral, and still get a numerical value out of the iteration?
Do any of you have any suggestions to how we might solve this?
Using numerical integration
Explanation of the input parameters: x is a vector of numerical values, all the rest are constants. A problem with my code is that the input parameter x is not being used (I guess this means that x is being treated as a symbol).
It looks like you can do a nesting of anonymous functions in MATLAB:
f =
#(x)2*x
>> ff = #(x) f(f(x))
ff =
#(x)f(f(x))
>> ff(2)
ans =
8
>> f = ff;
>> f(2)
ans =
8
Also it is possible to rebind the pointers to the functions.
Thus, you can set up your iteration like
delta_old = #(x) delta_a(x)
for i=1:500
delta_new = #(x) delta_old(x) - integral(#(xi),delta_old(xi))
delta_old = delta_new
end
plus the inclusion of your parameters...
You may want to consider to solve a discretized version of your problem.
Let K be the matrix which discretizes your Fredholm kernel k(t,s), e.g.
K(i,j) = int_a^b K(x_i, s) l_j(s) ds
where l_j(s) is, for instance, the j-th lagrange interpolant associated to the interpolation nodes (x_i) = x_1,x_2,...,x_n.
Then, solving your Picard iterations is as simple as doing
phi_n+1 = f + K*phi_n
i.e.
for i = 1:N
phi = f + K*phi
end
where phi_n and f are the nodal values of phi and f on the (x_i).