I am using fminsearch to minimize objective function. This requires defining variable x0 (usually vector) as estimates of solution which algorithm uses as starting point of finding solution. However, I want to create many estimates and evaluate objective function for each of these estimates. I tried to define x0 as matrix of estimates, but I didn't get result I wanted.
Suppose each start parameter vector is stored in a row of x0, and fun is the function you want to minimize:
fun = #(x)100*(x(2) - x(1)^2)^2 + (1 - x(1))^2;
x0 = [-1.2, 1; -1.3, 2; 7 3.3];
for i = 1:size(x0,1)
x(i,:) = fminsearch(fun,x0(i,:))
endfor
final output:
x =
1.00000 1.00001
1.00000 0.99999
0.99997 0.99995
Related
In the integral
I want to optimize the function Dt, as I know the end result of the integral. I have expressions for k1 and k0 in terms of k2 and N, and it is k2 and N that I would like to optimize. They have constraints, needing to be between certain values. I have it all setup in my code, but I am just unaware of how to tell the genetic alogrithm to optimize an integral function? Is there something I'm missing here? The integral is usually evaluated numerically but I am trying to go backwards, and assuming I know an answer find the input parameters
EDIT:
All right, so here's my code. I know the integral MUST add up to a known value, and I know the value, so I need to optimize the variables with that given parameter. I have created an objective function y= integral - DT. I kept theta as syms because it is the thing being integrated to give DT.
function y = objective(k)
% Define constants
AU = astroConstants(2);
mu = astroConstants(4);
% Define start and finish parameters for the exponential sinusoid.
r1 = AU; % Initial radius
psi = pi/2; % Final polar angle of Mars/finish transfer
phi = pi/2;
r2 = 1.5*AU;
global k1
k1 = sqrt( ( (log(r1/r2) + sin(k(1)*(psi + 2*pi*k(2)))*tan(0)/k(1)) / (1-
cos(k(1)*(psi+2*pi*k(2)))) )^2 + tan(0)^2/k(1)^2 );
k0 = r1/exp(k1*sin(phi));
syms theta
R = k0*exp(k1*sin(k(1)*theta + phi));
syms theta
theta_dot = sqrt((mu/(R^3))*1/((tan(0))^2 + k1*(k(1))^2*sin(k(1)*theta +
phi) + 1));
z = 1/theta_dot;
y = int(z, theta, 0,(psi+2*pi*k(2))) - 1.3069e08;
global x
x=y;
end
my k's are constrained, and the following is the constraint function. I'm hoping what I have done here is tell it that the function MUST = 0.
function [c,c_eq] = myconstraints(k)
global k1 x
c = [norm(k1*(k(1)^2))-1 -norm(k1*(k(1)^2))];
c_eq =[x];
end
And finally, my ga code looks like this. Honestly, I've been playing with it all night and getting error messages after error messages - ranging from "constraint function must return real value" to "error in fcnvectorizer" and "unable to convert expression into double array", with the last two coming after i've removed the constraints.
clc; clear;
ObjFcn = #objective;
nvars = 2
LB = [0 2];
UB = [1 7];
ConsFcn = #myconstraints;
[k,fval] = ga(ObjFcn,nvars,[],[],[],[],LB,UB,ConsFcn);
I've been stuck on this problem for weeks and have gotten nowhere, even with searching through literature.
How to solve the function f(x)=ln(x^2)-0.7=0 with a known Matlab command?
clc;clear all;close all;
f(x)=ln(x^2)-0.7=0
B=sqrt f(x)
You can use symbolic variables together with the solve function:
syms x;
eqn = log(x^2) - 0.7 == 0;
solve(eqn,x)
The above code will output:
ans =
exp(7/20)
-exp(7/20)
Since the equation is quadratic, the solver returns two distinct solutions (often people forget that quadratic equations may have two specular solutions, one positive and one negative).
If you want to retrieve the numerical values (for example, in order to calculate their sqrt value):
sol = solve(eqn,x);
num = double(sol)
num =
1.4191
-1.4191
Put the following code into a MATLAB script, name it "main.m".
function b=main
clc
x=solveF()
y=f(x)
b=sqrt(y)
end
function y=f(x)
y=log(x^2)-0.7
end
function x=solveF()
g = #(x) abs(f(x)-0)
x = fminsearch(g, 1.0)
end
Then run it as:
main
You will get the results:
x =
1.4190
y =
-3.4643e-05
b =
0.0000 + 0.0059i
ans =
0.0000 + 0.0059i
You can define equations in matlab as such:
f = #(x) log(x^2)-0.7;
B = #(x) sqrt(f(x));
If you want to find the value of x satisfying a constraint you can design a function that will be equal to zero when the constraint is respecte, then call fminsearch to find x:
f_constraint = #(x) abs(f(x)-0);
x_opt = fminsearch(f_constraint, 1.3); % function handle, initial estimate
In your example, B(x_opt) should be equal to zero. This is not exactly the case as fminsearch estimated a solution.
Problem: when doing feature normalisation in Octave, zero-variance input causes div-zero errors.
Question: Is there a nice(r) way to handle div-zero when working with vectorised data?
Example:
Input is a matrix containing multiple datasets in columns:
X = [1 3.5 7.5 9 ;
1 4 8 9 ;
1 4.5 8.5 9]
So X contains three series: x_1 = [1,1,1], x_2 = [7.5, 8, 8.5], and x_3 = [9,9,9]. In order to normalise each set using vectorisation the following approach seems sensible:
mu = mean(X);
sigma = std(X);
X_norm = (1 ./ sigma) .* (X - mu);
However, the above approach will fail because both x_1 and x_3 have zero variance and so division-by-zero errors will occur.
My preferred handling of zero variance data is to set sigma to 1. Currently I'm using the following kludge:
dataset_size = length(sigma);
for index = 1:dataset_size
if sigma(index) == 0
sigma(index) = 1;
endif
end
Notes:
Broadcasting is being used twice here, in the division and subtraction operations
this example is based in Octave, but the question may be equally applicable to MATLAB.
this example is simple for illustration - 'real' usage would have more, larger datasets
this example will treat zero-variance data differently from regular data (imperfect by pragmatic)
zscore sounded relevant, but is (as the name suggests) better suited to calculating a z-score...
Why not just this?
mu = mean(X);
sigma = std(X);
sigma(sigma==0) = 1; %// add this line to remove zeros
X_norm = (1 ./ sigma) .* (X - mu);
Or, to save some operations:
mu = mean(X);
sigma = std(X);
ind = sigma~=0; %// detect zero values
X_norm = X - mu;
X_norm(:,ind) = X_norm(:,ind) ./ sigma(ind) ;
In general, it may be preferable to use
sigma(sigma<=tol) = 1; %// add this line to remove values close to zero
in the first approach, or
ind = sigma>tol; %// detect values close to zero
in the second, for a given tolerance tol (for example tol = 1e-10). This is a better way in applications where finite-precision errors can produce values such as 1e-15 instead of zero.
Is it possible to use the size (s) of the points to 'weight' the line of best fit?
x = [1 2 3 4 5];
y = [2 4 5 3 4];
s = [10 15 20 2 5];
scatter(x,y,s)
hold on
weight = s;
p = polyfit(x,y,1); %how do I take into account the size of the points?
f = polyval(p,x);
plot(x,f,'-r')
Using Marcin's suggestion, you can incorporate lscov into polyfit. As the documentation explains, polynomial fitting is done by computing the Vandermonde matrix V of x, and then executing p = V\y. This is the standard formalism of any least-squares solution, and lends itself to weighted-least-squares in MATLAB through lscov.
Taking your x, y and weight vectors, instead of calling polyfit(x,y,n) you can do the following:
% Construct Vandermonde matrix. This code is taken from polyfit.m
V(:,n+1) = ones(length(x),1,class(x));
for j = n:-1:1
V(:,j) = x.*V(:,j+1);
end
% Solve using weighted-least-squares
p = lscov(V,y,weight);
You can even go one step further, and modify polyfit.m itself to include this functionality, or add another function polyfitw.m if you are not inclined to modify original MATLAB functions. Note however that polyfit has some more optional outputs for structure, computed using QR decomposition as detailed in the documentation. Generalization of these outputs to the weighted case will require some more work.
x = (1:10)';
y = (3 * x + 5) + rand(length(x),1)*5;
w = ones(1,length(y));
A = [x ones(length(x),1)];
p = lscov(A,y,w);
plot(x,y,'.');
hold on
plot(x,p(1)*x + p(2),'-r');
I'm trying to use fmincon in MATLAB and not quite sure what the heck the problem is. My function is:
function f = myfun(x4)
f = (C * x4 - d) .^ 2;
end
and I call it like this:
lb = zeros(3, 1);
x0 = [10; 10; 10];
[x4, fvalx4, exitflagx4, outputx4, lambdax4] = fmincon(#myfun,x0,[],[],[],[],lb,[]);
but when I run it I get
??? Error using ==> mtimes
Inner matrix dimensions must agree.
However, I checked and C is 112x3, and d is 112x1, and x4 is not initialized at all because that's what I'm trying to solve for. If I create a "dummy" x4 I can run
(C * x4 - d) .^ 2
without a problem.
Any thoughts? I realize this is the same as using lsqr or rather lsqlin with a lb of 0, which is also equivalent to lsqnonneg, but that's the point: I'm trying to verify results from those methods in different ways.
There are several issues here.
First, you need to learn how to pass in those parameters that are not optimized. The function myfun cannot see C and d, as functions have their own workspaces, unless they are nested functions.
Next, since you are computing a linear least squares subject to constraints, you need to return a sum of squares. fmincon needs a scalar objective. It does not understand what to do when you return a vector.
Personally, I would not even bother defining an explicit m-file. Define this using a function handle. So perhaps you might try this objective:
myfun = #(x4) norm(C*x4 - d);
lb = zeros(3, 1);
x0 = [10; 10; 10];
[x4, fvalx4, exitflagx4, outputx4, lambdax4] = fmincon(myfun,x0,[],[],[],[],lb,[]);
The function handle can see the value of C and d, so once the handle is created, those variables are carried along inside the function handle workspace.
Notice that I used norm to compute the sum of squares, in fact, here a sqrt of a sum of squares. But where the sum of squares is minimized, then so is the sqrt of that number. Its a bit cleaner looking with norm.
Another option is to use a version of myfun that explicitly passes in the value of C and d. Here I've given myfun arguments, then essentially created a function handle wrapper around myfun. You could have done that with an m-file version of myfun too.
myfun = #(x4,C,d) norm(C*x4 - d);
lb = zeros(3, 1);
x0 = [10; 10; 10];
[x4, fvalx4, exitflagx4, outputx4, lambdax4] = fmincon(#(x4) myfun(x4,C,d),x0,[],[],[],[],lb,[]);
The function that you pass to fmincon should return a scalar value. In your function it returns a 112-by-1 vector. Maybe you need to change
f = (C * x4 - d) .^ 2;
to
f = sum((C * x4 - d) .^ 2);