Algorithm to find a value that gives the minimum output for two or equations - matlab

Suppose I have two equations with only one variable (free parameter) x and that k1 and k2 are constants. I would like to solve for:
f(x) + k1 = 0
&
g(x) + k2 = 0
...
h(x) + kn = 0
Of course there is no value of x that satisfies all of these equations. I basically would like the value of x that minimizes the output of each of these equations.
'solve' in matlab looks for an exact answer and returns an error, here's an example to demonstrate:
syms x
solution = solve(0.5*(x-k1)/sqrt(2) == 0, 0.5*(x-k2)/sqrt(2) == 0);

You can try using Unconstrained Optimization method such as fminsearch, for example:
h=#(x) x^2;
g=#(x) x^3;
k1=2;
k2=4;
inital_guess=3;
f = #(x) sum(abs([h(x)+k1; g(x)+k2]));
[x,fval] = fminsearch(f,inital_guess)
Note that I represent both eq in matrix form, and the minimization is by looking at the sum of their absolute values.
For the values I entered the value of x that minmize these eq is given by the output x = -1.5874

Related

How to describe the derivative of matlab symbolic variable?

For example, I named the variables x(t), xdot(t) about time: syms t x(t) xdot(t);, and the derivative of x about time is xdot, xdot=diff(x,t).
But when I calculate diff (x, t), the result is not xdot. How can I set the display of diff (x, t) in the calculation result to xdot?
In addition, the time variable in the calculation result is displayed in the form of variable(t). How to set the result to display only variable?
syms t x(t) xdot(t);
xdot=diff(x,t);
y=diff(x,t);
y
the result of y is displayed as , however, I want it to be xdot
Consider the following code:
a = 3;
b = 3;
b
It appears to me, you would like this to display b = a, instead of b = 3. This is not how MATLAB works. Both a and b are equal to 3, but that doesn't mean a is b.
The same is true for the code:
a = 3;
b = a;
b
This gives b = 3, not b = a. I won't go into details about why this is the case (and why it has to be the case in MATLAB). It's enough to know that this is how it works.
You have assigned diff(x,t) to two different variables, xdot and y. This means that, while xdot and y have the same value, xdot is not y.
If you do xdot = 3 after your code, then y would still be dx/dt.
Side note: Why do you want this behaviour? Are you sure it's necessary? You can always print the result however you like:
fprintf('xdot = %s', y(t))
xdot = diff(x(t), t)
Ugly workaround to do something I don't understand why you would do:
Create a function:
function res = xdot(t)
syms x(t) res;
res = diff(x,t);
end
And then define y as a function handle:
y = #xdot
y = function_handle with value:
#xdot
Now y(t) will still give dx/dt, but y will give xdot
I strongly recommend you don't do this.

How to use matlab to quickly judge whether a function is convex?

For example, FX = x ^ 2 + sin (x)
Just for curiosity, I don't want to use the CVX toolbox to do this.
You can check this within some interval [a,b] by checking if the second derivative is nonnegative. For this you have to define a vector of x-values, find the numerical second derivative and check whether it is not too negative:
a = 0;
b = 1;
margin = 1e-5;
point_count = 100;
f=#(x) x.^2 + sin(x);
x = linspace(a, b, point_count)
is_convex = all(diff(x, 2) > -margin);
Since this is a numerical test, you need to adjust the parameter to the properties of the function, that is if the function does wild things on a small scale we might not be able to pick it up. E.g. with the parameters above the test will falsely report the function f=#(x)sin(99.5*2*pi*x-3) as convex.
clear
syms x real
syms f(x) d(x) d1(x)
f = x^2 + sin(x)
d = diff(f,x,2)==0
d1 = diff(f,x,2)
expSolution = solve(d, x)
if size(expSolution,1) == 0
if eval(subs(d1,x,0))>0
disp("condition 1- the graph is concave upward");
else
disp("condition 2 - the graph is concave download");
end
else
disp("condition 3 -- not certain")
end

Series expansion of a function about infinity - how to return coefficients of series as a Matlab array?

This question is connected to this one. Suppose again the following code:
syms x
f = 1/(x^2+4*x+9)
Now taylor allows the function f to be expanded about infinity:
ts = taylor(f,x,inf,'Order',100)
But the following code
c = coeffs(ts)
produces errors, because the series does not contain positive powers of x (it contains negative powers of x).
In such a case, what code should be used?
Since the Taylor Expansion around infinity was likely performed with the substitution y = 1/x and expanded around 0, I would explicitly make that substitution to make the power positive for use on coeffs:
syms x y
f = 1/(x^2+4x+9);
ts = taylor(f,x,inf,'Order',100);
[c,ty] = coeffs(subs(ts,x,1/y),y);
tx = subs(ty,y,1/x);
The output from taylor is not a multivariate polynomial, so coeffs won't work in this case. One thing you can try is using collect (you may get the same or similar result from using simplify):
syms x
f = 1/(x^2 + 4*x + 9);
ts = series(f,x,Inf,'Order',5) % 4-th order Puiseux series of f about 0
c = collect(ts)
which returns
ts =
1/x^2 - 4/x^3 + 7/x^4 + 8/x^5 - 95/x^6
c =
(x^4 - 4*x^3 + 7*x^2 + 8*x - 95)/x^6
Then you can use numden to extract the numerator and denominator from either c or ts:
[n,d] = numden(ts)
which returns the following polynomials:
n =
x^4 - 4*x^3 + 7*x^2 + 8*x - 95
d =
x^6
coeffs can then be used on the numerator. You may find other functions listed here helpful as well.

feval with multivariate function and vectorization

I need feval called with a bivariate function f and two vectors v1 and v2 (let us say that v1 are the x's and v2 the y's) to return a vector z=[f(v1(1),v2(1)) ... f(v1(n),v2(n)].
How can I do that ?
The following example does not work:
function z = f(x,y)
if x>0.5
z=x+y;
else
z=x+2*y;
end
end
indeed,
feval(f,[0.4 2 3],[4 5 6])
returns: [8.4 12 15]
instead of [8.4 7 9].
What is the correct syntax ?
The if condition doesn't work element-wise, as you seem to expect. Rather, the if branch is entered only if all the elements in the expression (x>0.5 in your case) evaluate to true.
To achieve what you want, change your function to
function z = f(x,y)
ind = x>.5;
z(ind) = x(ind) + y(ind);
z(~ind) = x(~ind) + 2*y(~ind);
end
Note that the logical index ind takes the place of your if.
For your particular function, the code could be simplified to
function z = f(x,y)
z = x + y + (x<=.5).*y;
end

create a polynomial matlab

I have got vector of coefficients v=[v1, v2, v3] (added by user).
I want to create a polynomial in a function. I would like to have a function fun(x), which solution will be my polynomial. After that I want to have a graph of this polynomial.
This is my idea but it doesn't work. Could you have any ideas how to improve it?
function [v] = createPolynomial(x)
r = length(v);
fun=0;
for i=r:1
fun=fun+v(i)*x.^(r-1);
end
You're pretty close! Is this what you want?
function f = createPoly(v,x)
n = length(v);
f = 0;
for ii = 1:n
f = f + v(ii)*x.^(n-ii+1);
end
end
f = createPoly([1 2 3 5],4)
f =
113
%% (1*4^3) + (2*4^2) + (3*4^1) + (5*4^0) = 113
Some errors in your code:
function [v] = createPolynomial(x)
As I understand it, you want both v and x as inputs to your function, and get a value back. Then you must do function value = createPolynomial(v, x), where valuewill be the output variable.
fun=fun+v(i)*x.^(r-1);
I guess this is just a typo, but .^r-1 is a constant value. You probably want the exponent to go from n, n-1, ... 1, 0 In that case you want r-i. And if I don't point it out, someone else will definitely do: Using i as a variable in MATLAB is not good practice if you are sometimes dealing with complex numbers.
And I guess you know this, but I'll say it anyway: You m-file must have the same name as you function.
If you want to input x as a vector, you must initialize f as a vector having the same length as x. That is:
f = zeros(1,length(x));
Now, you can do:
f = createPoly([1 2 3 5],1:5)
f =
11
27
59
113
195
you define coefficients in the following form of variable p
% example :
p =[ 2 1 3] % coefficients
x=0:0.2:5; % values at which it is to be evaluated
y=polyval(p, x);
plot(x,y)
polyval is provided in standard matlab, it evaluates the polynomial. see help polyval