Linearize non-linear constraint (product of two continuous variables) - nonlinear-optimization

I have a problem with linearizing a constraint because of the product of two continuous variables.
Suppose that the non-linear constraint is A = b + x1 x2 : A,x1,x2 are non-negative continuous variables.
How can I linearize this constraint?
I tried to reformulate it by creating two new continuous variables (y1 and y2)
where y1 = 1/2 (x1 + x2) and y2= 1/2 (x1 - x2).
In this case, the constraint also becomes non-linear.
What should I do?

There is no exact way to linearize w=x*y if x and y are continuous.
The reformulation z1 = 1/2 (x + y) and z2 = 1/2 (x - y) gives w = z1^2 - z2^2. This is indeed still non-linear, but this is easier to handle when using a piecewise linear approximation.
You can use McCormick envelopes (https://optimization.mccormick.northwestern.edu/index.php/McCormick_envelopes). But this gives just an approximation. To get more precision, split the range in segments.
Sometimes (in special cases) a logarithmic transform can help.
Some solvers can handle this quadratic expression directly.

Related

Monte Carlo integration of exp(-x^2/2) from x=-infinity to x=+infinity

I want to integrate
f(x) = exp(-x^2/2)
from x=-infinity to x=+infinity
by using the Monte Carlo method. I use the function randn() to generate all x_i for the function f(x_i) = exp(-x_i^2/2) I want to integrate to calculate afterwards the mean value of f([x_1,..x_n]). My problem is, that the result depends on what values I choose for my borders x1 and x2 (see below). My result is going far away from the real value by increasing the value of x1 and x2. Actually the result should be better and better by increasing x1 and x2.
Does someone see my mistake?
Here is my Matlab code
clear all;
b=10; % border
x1 = -b; % left border
x2 = b; % right border
n = 10^6; % number of random numbers
x = randn(n,1);
f = ones(n,1);
g = exp(-(x.^2)/2);
F = ((x2-x1)/n)*f'*g;
The right value should be ~2.5066.
Thanks
Try this:
clear all;
b=10; % border
x1 = -b; % left border
x2 = b; % right border
n = 10^6; % number of random numbers
x = sort(abs(x1 - x2) * rand(n,1) + x1);
f = exp(-x.^2/2);
F = trapz(x,f)
F =
2.5066
Ok, lets start with writing of general case of MC integration:
I = S f(x) * p(x) dx, x in [a...b]
S here is integral sign.
Usually, p(x) is normalized probability density function, f(x) you want to integrate, and algorithm is very simple one:
set accumulator s to zero
start loop of N events
sample x randomly from p(x)
given x, compute f(x) and add to accumulator
back to start loop if not done
if done, divide accumulator by N and return it
In simplest textbook case you have
I = S f(x) dx, x in [a...b]
where it means PDF is equal to uniformly distributed one
p(x) = 1/(b-a)
but what you have to sum is actually (b-a)*f(x), because your integral now looks like
I = S (b-a)*f(x) 1/(b-a) dx, x in [a...b]
In general, if both f(x) and p(x) could serve as PDF, then it is matter of choice whether you integrate f(x) over p(x), or p(x) over f(x). No difference! (Well, except maybe computation time)
So, back to particular integral (which is equal to \sqrt{2\pi}, i believe)
I = S exp(-x^2/2) dx, x in [-infinity...infinity]
You could use more traditional approach like #Agriculturist and write it
I = S exp(-x^2/2)*(2a) 1/(2a) dx, x in [-a...a]
and sample x from U(0,1) in [-a...a] interval, and for each x compute exp() and average it and get the result
From what I understand, you want to use exp() as PDF, so your integral looks like
I = S D * exp(-x^2/2)/D dx, x in [-infinity...infinity]
PDF to be normalized so it shall include normalization factor D, which is exactly equal to \sqrt{2 \pi} from gaussian integral.
Now f(x) is just a constant equal to D. It doesn't depend on x. It means that you for each sampled x should add to accumulator a CONSTANT value of D. After running N samples,
in accumulator you'll have exactly N*D. To find mean you'll divide by N and as a result you'll get perfect D, which is \sqrt{2 \pi}, which, in turn, is
2.5066.
Too rusty to write any matlab, and Happy New Year anyway

How to calculate cumulative distibution functions in matlab

How to solve the following problem, not quite sure how to do it, using the MATLAB functions: binocdf, normcdf, expcdf:
This is given:
X1 ∈ Bin(10, 0.3), X2 ∈ N(5, 3), X3 ∈ Exp(7)
k = 1, 2, 3
What is this probability P(3 < Xk ≤ 4) = ?
I know that the cumulative distribution function gives you the probability of a stochastic variable of being less than or equal to the input if you use for example:
binocdf(4,10,0.3) = P(X1 ≤ 4)
But how do I use these functions when it's Xk > 3?
If you remember the properties of a CDF, you can find the probability of an event of a random variable spanned by an interval [a,b] by simply substituting each end point into the CDF and subtracting the two quantities. Concretely, given f being the PDF and F being the CDF of a random variable X, calculating the probability of the event occurring P(a < X <= b) is such that:
Source: Wikipedia
Therefore, to compute P(3 < X1 <= 4) as for your example, do:
out = binocdf(4,10,0.3) - binocdf(3,10,0.3);
I'll leave it to you to figure out the other ones.

Complicated Nonlinear system Numerical differentiating

I have a nonlinear steady space matrix.I need to solve the differential as shown in the pic below:
I explained more on pic(Here dD/dx)
You can do symbolic differentation with the MATLAB Symbolic Toolbox, but you have to tell it to perform the right partial derivatives. Your dependent variable (x) has three components, so you cannot take the partial derivative of D with respect to x, but you can take the partial derivative with respect to x1, x2, and x3.
syms t x1 x2 x3 x1_dot x2_dot x3_dot
x1_dot = diff(x1, t)
x2_dot = diff(x2, t)
x3_dot = diff(x3, t)
D(x1,x2,x3) = [... your function matrix ... ]
dD_x1 = diff(D,x1)
dD_x2 = diff(D,x2)
dD_x3 = diff(D,x3)

Correlation dependent on samples

I have a variable y that depends on some variables x1 ∈ [x1_min,x1_max], x2 ∈ [x2_min,x2_max], x3 ∈ [x3_min,x3_max] and y can be a matrix as well, i.e. y=y(x1,x2,x3). I want to detect which among x1,x2,x3 is less relevant to determine the value of y.
I am using the following code in Matlab:
x = rand(1000,3); % x1, x2, x3 are the columns of x
y = fct(x); % A generic function of x1, x2, x3
[corr_mat, p_val] = corrcoef(x,y);
[i,j] = find(p_val > 0.5);
disp([i,j])
The problem is that the resulting indices strongly depend on the random samples (even if I increase the number of samples). How can I get a more precise measure?
As a simple alternative example, y=x1+x2+x3, with x1∈[50,80], x2∈[0,1], x3∈[0,1]. Clearly, the value of y depends much more on x1 than the other 2 variables. How do I quantify this dependence?
Thank you in advance.
EDIT: Here is what I mean with "quantification" or "relevance". I want to detect which variable determines very small changes in y, i.e. in the previous example x2 and x3 makes y to vary less than x1 does.
You need to use covariance and not correlation coefficient. The correlation coefficient is normalized by the variance of each variable to give the same weight to all variables when they have different ranges, and this is exactly what you want to avoid.
x1 = 50+30*rand(1000,1);
x2 = rand(1000,1);
x3 = rand(1000,1);
y = x1+x2+x3;
c=cov([x1 x2 x3 y]);
c(1:3,4) % Covariances of x[1-3] and y

MATLAB - Intersection of arrays

I am trying to graphically find the intersections between two surfaces and the x-y plane. (Intersection of surface z1 with the x-y plane and intersection z2 with the x-y plane)
I have created arrays representing the surfaces z1 = 3+x+y and z2 = 4-2x-4y and the z3 for the x-y plane using meshgrid. Looking everywhere, the only command that seems I can use to find the intersections between arrays is the intersect(A,B) command where A and B are arrays. When I enter intersect(z1,z3) however, I get the error "A and B must be vectors, or 'rows' must be specified." When I try intersect (z1,z2,'rows'), I am returned a 0-by-21 empty matrix. What am I doing wrong here?
My code:
x = -10:10;
y = -10:10;
[X,Y] = meshgrid(x,y);
z1 = 3+X+Y;
z2 = 4-2.*X-4.*Y;
z3 = 0.*X+0.*Y; %x-y plane
surf(X,Y,z1)
hold on
surf(X,Y,z2)
surf(X,Y,z3)
int1 = intersect(z1,z3,'rows');
int2 = intersect(z2,z3,'rows');
It sounds like you want the points where z1 = z2. To numerically find these, you have a couple options.
1) Numerical rootfinding: fsolve is capable of solving systems of equations. You can formulate the surfaces as functions of one vector, [x;y] and solve for the vector that makes the two surfaces equal. An example using the initial guess x=1, y=1 follows:
z1 = #(x) 3 + x(1) + x(2);
z2 = #(x) 4 - 2*x(1) - 4*x(2);
f = #(x) z1(x) - z2(x);
x0 = [1;1]
intersect = fsolve(#(x) f(x), x0);
2) Minimizing the error: If you are stuck with discrete data (arrays instead of functions) you can simply find the points where z1 - z2 is closest to zero. An easy starting point is to take the arrays Z1 and Z2 and find all points where the difference nears zero:
tol = 1e-3;
near_zero = abs(Z1 - Z2) < tol;
near_zero is going to be a logical array that is true whenever the difference between Z1 and Z2 is small relative to tol. You can use this to index into corresponding meshgrid arrays for X and Y to find the coordinates of intersection.
a simple way (no major function calls) to solve this is as follows:
x = -10:.1:10;
y = -10:.1:10;
[X,Y] = meshgrid(x,y);
z1 = 3+X+Y;
z2 = 4-2.*X-4.*Y;
z3 = z1 - z2;
[~,mn] = min(abs(z3));
the intersection is defined as (x, y(mn)).
This, of course is a numerical approximation (since you wanted a numerical method), subject to boundary condition which I haven't explored (you'll need to disregard values far from zero when performing the minimum function)
Note: if you're looking for an equation, consider performing a least squares approximation on the resulting data.