Are there any way to solve for an unknown variable instead of using solve? - matlab

I write code to do optimization to solve a problem taking the form min_x f(x,c) s.t. sum(x)=1 and g(x,c)=1, where x is a vector and c is a function of x such that c(x) is a constant when x is fixed. Indeed, g(x,c) takes the following form
n=5; N=1000000; idx = 1:1:n; df=4; theta=2; alpha=2.4;
central_Simulation_Points=mvtrnd(eyes(n),df,N);
x=sym('x_%d',[n,1]); syms c
g(x,c)=1./N.*sum((theta.*(alpha-1).*central_Simulation_Points*x).^2+c).^(1./(alpha-1)))==1;
Constraint_equ = solve(g(x,c), c);
Constraint_equ_handle = matlabFunction(Constraint_equ);
The use of solve is to express c in terms of x, while matlabFunction changes the symbolic function to function handle for input. I then define an objective function obj_fun=#(x)f(x,c(x)). The objective function for optimization is
(alpha-1)/alpha*sum_{i=1}^N[(theta*(alpha-1)*V(x,Xi)+c)^(1/(alpha-1))*V(x,Xi)]+c/(theta*alpha*(1-alpha))
V(x,Xi) is any function. I use (x^{T}Xi)^2. Xi is the i-th row of central_Simulation_Points.
When I count the the time, Equ = 1./N.*sum((theta.*(alpha-1).*central_Simulation_Points*x).^2+c).^(1./(alpha-1)))==1; takes 203 seconds to run, but it seems that Constraint_equ = solve(Equ, c); never makes the program stops. I wonder if any other methods could be used instead of using
Constraint_equ = solve(Equ, c);
Constraint_equ_handle = matlabFunction(Constraint_equ);
Are there any ways to find c in terms of x, or any ways to modify the code?

Related

How to create a function that takes a matrix as an input?

I am new to MatLab.
Write a function that takes as input a matrix D ∈ R^(N×2), D_i = (x_i,y_i), and the period ω and returns a plot showing a fit of the data without noise.
I need help with creating the function that takes the input as a matrix and period ω. Here is what I have so far. Am I on the right track?
function F = fftfuntion(D, omega)
check = 0;
x = D(:,1);
y = D(;,2);
You are on track but there are 3 problems:
First: you are using p variable inside your function which is not defined there. If it is defined in your main code you have to insert it to this function by adding an input to your function as p and when the function is called you have to put p there. Your other solution is to set p as a global variable which is not recommended.
function F = fftfuntion(D, omega,p)
Second: you have said that you need omega as an input and you are changing it with omega = 2*pi which is not right.
Finally I don't see any output which I think that's because you are not still done with the function.
Good luck

Use symbolic matlab for flexible number of arguments and functions

I have a function F which takes as an input a vector a. Both the output of the function and a are vectors of length N, where N is arbitrary. Each component Fn is of the form g(a(n),a(n-k)), where g is the same for each component.
I want to implement this function in matlab using its symbolic functionality and calculate its Jacobian (and then store both the function and its jacobian as a regular .m file using matlabFunction). I know how to do this for a function where each input is a scalar that can be handled manually. But here I want a script that is capable of producing these files for any N. Is there a nice way to do this?
One solution I came up with is to generate an array of strings "a0","a1", ..., "aN" and define each component of the output using eval. But this is messy and I was wondering if there is a better way.
Thank you!
[EDIT]
Here is a minimal working example of my current solution:
function F = F_symbolically(N)
%generate symbols
for n = 1:N
syms(['a',num2str(n)]);
end
%define output
F(1) = a1;
for n = 2:N
F(n) = eval(sprintf('a%i + a%i',n,n-1));
end
Try this:
function F = F_symbolically(N)
a = sym('a',[1 N]);
F = a(1);
for i=2:N
F(i) = a(i) + a(i-1);
end
end
Note the use of sym function (not syms) to create an array of symbolic variables.

How to write a very long sum in a fitness function for global optimisation in Matlab

I a struggling writing a fully parametrised fitness function for the global optimisation toolbox in matlab.
Approach:
[x fvall,exitflag,output]=ga(fitnessfcn,nvars,A,b,Aeq,beq,lb,ub)
I have a fitness function that I call with
fitnessfcn=#fitnessTest;
hence, the function is stated in a separate file.
Problem:
My issue is now that my optimisation is a simple but super long sum like
cost=f1*x1+f2x2+...fnxn
n should be parameterised (384 at the moment). In all matlab help files, the objective function is always short and neat like
y = 100 * (x(1)^2 - x(2)) ^2 + (1 - x(1))^2;
I have tried several approaches "writing" the objective function intelligently, but then, I cannot call the function correctly:
if I write the fitness function manually (for fi=1)
function y = simple_fitness(x)
y = x(1)+ x(2)+ x(3)+ x(4)+ x(5)+ x(6)+ x(7)+ x(8);
the global optimisation works
But if I use my automated approach:
n = 8; %# number of function handles
parameters = 1:1:n;
store = cell(2,3);
for i=1:n
store{1,i} = sprintf('x(%i)',parameters(i));
store{2,i} = '+'; %# operator
end
%# combine such that we get
%# sin(t)+sin(t/2)+sin(t/4)
funStr = [store{1:end-1}];%# ignore last operator
endFunction=';';
%functionHandle = str2func(funStr)
y=strcat(funStr,endFunction)
matlab does not recognise the function properly:
error:
Subscripted assignment dimension mismatch.
Error in fcnvectorizer (line 14)
y(i,:) = feval(fun,(pop(i,:)));
thanks! I cannot write the objective function by hand as I will have several hundred variables.
You can use the sum(x) directly using function handle, instead of writing all indexes, do: fitnessfcn = #(x) sum(x).

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).

MATLAB Function (Solving an Error)

I have one file with the following code:
function fx=ff(x)
fx=x;
I have another file with the following code:
function g = LaplaceTransform(s,N)
g = ff(x)*exp(-s*x);
a=0;
b=1;
If=0;
h=(b-a)/N;
If=If+g(a)*h/2+g(b)*h/2;
for i=1:(N-1)
If=If+g(a+h*i)*h;
end;
If
Whenever I run the second file, I get the following error:
Undefined function or variable 'x'.
What I am trying to do is integrate the function g between 0 and 1 using trapezoidal approximations. However, I am unsure how to deal with x and that is clearly causing problems as can be seen with the error.
Any help would be great. Thanks.
Looks like what you're trying to do is create a function in the variable g. That is, you want the first line to mean,
"Let g(x) be a function that is calculated like this: ff(x)*exp(-s*x)",
rather than
"calculate the value of ff(x)*exp(-s*x) and put the result in g".
Solution
You can create a subfunction for this
function result = g(x)
result = ff(x) * exp(-s * x);
end
Or you can create an anonymous function
g = #(x) ff(x) * exp(-s * x);
Then you can use g(a), g(b), etc to calculate what you want.
You can also use the TRAPZ function to perform trapezoidal numerical integration. Here is an example:
%# parameters
a = 0; b = 1;
N = 100; s = 1;
f = #(x) x;
%# integration
X = linspace(a,b,N);
Y = f(X).*exp(-s*X);
If = trapz(X,Y) %# value returned: 0.26423
%# plot
area(X,Y, 'FaceColor',[.5 .8 .9], 'EdgeColor','b', 'LineWidth',2)
grid on, set(gca, 'Layer','top', 'XLim',[a-0.5 b+0.5])
title('$\int_0^1 f(x) e^{-sx} \,dx$', 'Interpreter','latex', 'FontSize',14)
The error message here is about as self-explanatory as it gets. You aren't defining a variable called x, so when you reference it on the first line of your function, MATLAB doesn't know what to use. You need to either define it in the function before referencing it, pass it into the function, or define it somewhere further up the stack so that it will be accessible when you call LaplaceTransform.
Since you're trying to numerically integrate with respect to x, I'm guessing you want x to take on values evenly spaced on your domain [0,1]. You could accomplish this using e.g.
x = linspace(a,b,N);
EDIT: There are a couple of other problems here: first, when you define g, you need to use .* instead of * to multiply the elements in the arrays (by default MATLAB interprets multiplication as matrix multiplication). Second, your calls g(a) and g(b) are treating g as a function instead of as an array of function values. This is something that takes some getting used to in MATLAB; instead of g(a), you really want the first element of the vector g, which is given by g(1). Similarly, instead of g(b), you want the last element of g, which is given by g(length(g)) or g(end). If this doesn't make sense, I'd suggest looking at a basic MATLAB tutorial to get a handle on how vectors and functions are used.