Checking intersection between two rectangles in answer set programming - answer-set-programming

The rule below checks for intersection.
:- areaCoords(X1,Y1,X2,Y2), areaCoords(XA,YA,XB,YB), XA >= X1, X2 >= XA, YB >= Y1, Y2 >= YA, (X1,Y1,X2,Y2) != (XA,YA,XB,YB).
However it generates symmetric pairs. That is, it checks for intersection(A,B) and intersection(B,A) obviously one of the checks is trivial. I detected it in the grounder. Here is the grounder output.
:-areaCoords(1,1,1,1),areaCoords(1,1,2,2).
:-areaCoords(1,1,2,2),areaCoords(1,1,1,1).
How can I prevent symmetric cases to occure?
In case the problem is somewhere else, I provide the full source that generates these rules.
Edit: I thought the previous version (full source) was very complicated for others to come to a conclution. So I simplified it. This code causes the above problem.
{ areaCoords(1,1,1,1); areaCoords(1,1,2,2) }.
:- areaCoords(X1,Y1,X2,Y2), areaCoords(XA,YA,XB,YB), XA >= X1, X2 >= XA, YB >= Y1, Y2 >= YA, (X1,Y1,X2,Y2) != (XA,YA,XB,YB).

Checking for < instead of inequality should prevent the symmetric constraint:
{ areaCoords(1,1,1,1); areaCoords(1,1,2,2) }.
:- areaCoords(X1,Y1,X2,Y2), areaCoords(XA,YA,XB,YB),
XA >= X1, X2 >= XA, YB >= Y1, Y2 >= YA,
(X1,Y1,X2,Y2) < (XA,YA,XB,YB).
Observe:
$ gringo --text <<<'{ areaCoords(1,1,1,1); areaCoords(1,1,2,2) }. :- areaCoords(X1,Y1,X2,Y2), areaCoords(XA,YA,XB,YB), XA >= X1, X2 >= XA, YB >= Y1, Y2 >= YA, (X1,Y1,X2,Y2) < (XA,YA,XB,YB).'
{areaCoords(1,1,1,1);areaCoords(1,1,2,2)}.
:-areaCoords(1,1,2,2),areaCoords(1,1,1,1).
vs.
$ gringo --text <<<'{ areaCoords(1,1,1,1); areaCoords(1,1,2,2) }. :- areaCoords(X1,Y1,X2,Y2), areaCoords(XA,YA,XB,YB), XA >= X1, X2 >= XA, YB >= Y1, Y2 >= YA, (X1,Y1,X2,Y2) != (XA,YA,XB,YB).'
{areaCoords(1,1,1,1);areaCoords(1,1,2,2)}.
:-areaCoords(1,1,1,1),areaCoords(1,1,2,2).
:-areaCoords(1,1,2,2),areaCoords(1,1,1,1).

Related

How to plot a surface plot with constraints

I'm trying to plot a function subject to three constraints (see code)
Now I tried the following
function value = example(x1, x2)
if x1 < 0 || x2 < 0 || x1+2*x2 > 6
value = NaN;
else
value = abs(x1 - x2) + exp(-x1 - x2);
end
[X, Y] = meshgrid(-10:10, -10:10);
Z = example(X,Y);
surf(X, Y, Z)
Now, this raises an error since the if clause cannot be evaluated for inputs X and Y. Any idea how to make this work?
As #Cris mentioned, use logical indexing.
The basic idea is (x1 < 0 | x2 < 0 | x1+2*x2 > 6) will gives you a matrix (same size as value) of zeros and ones. The positions of ones correspond to the true condition. Try this:
function value = example(x1, x2)
value = abs(x1 - x2) + exp(-x1 - x2);
value(x1 < 0 | x2 < 0 | x1+2*x2 > 6) = NaN;
Output:

Spurious solutions when solving system of equations

I'm trying to solve a system of equations in Matlab.
The system of equations is defined as follows:
syms x1 x2 lambda
Grad =
2*lambda*x1 + (8*x1*(((x2 - 10)^2 + x1^2)^(1/2) - 10))/((x2 - 10)^2 + x1^2)^(1/2) + (4*x1*(((x2 + 10)^2 + x1^2)^(1/2) - 10))/((x2 + 10)^2 + x1^2)^(1/2) - 5
2*lambda*x2 + (4*(((x2 - 10)^2 + x1^2)^(1/2) - 10)*(2*x2 - 20))/((x2 - 10)^2 + x1^2)^(1/2) + (2*(((x2 + 10)^2 + x1^2)^(1/2) - 10)*(2*x2 + 20))/((x2 + 10)^2 + x1^2)^(1/2) - 10
x1^2 + x2^2 - 36
I tried solving it using:
[X1 X2 LAMBDA] = solve([Grad(1) == 0, Grad(2) == 0, Grad(3) == 0],[x1, x2, lambda]);
and
[X1 X2 LAMBDA] = solve(Grad,[x1, x2, lambda]);
But I get the error:
Warning: Possibly spurious solutions.
> In symengine
In mupadengine/evalin (line 102)
In mupadengine/feval (line 158)
In solve (line 292)
In Ex (line 63)
I don't understand why Matlab does this, I have three equations with three variables, so Matlab should be able to find a solution right?
The answer can be fixed by substituting the values back into the equation and checking whether or not the values are correct:
[X1, X2, LAMBDA] = solve([Grad(1) == 0, Grad(2) == 0, Grad(3) == 0],[x1, x2, lambda]);
clc;
X1 = double(X1); X2 = double(X2); LAMBDA = double(LAMBDA);
X1 = real(X1); X2 = real(X2); LAMBDA = real(LAMBDA);
i = 1;
while i < 17
Sub(i,:) = subs(Grad,[x1, x2, lambda],[X1(i),X2(i),LAMBDA(i)]);
if abs(Sub(i,1)) < 0.00001 & abs(Sub(i,2)) < 0.00001 & abs(Sub(i,3)) < 0.00001
I(i,:) = i;
Var(i,1) = X1(i); Var(i,2) = X2(i); Var(i,3) = LAMBDA(3);
end
i = i + 1;
end
I already knew the approximate values of my x1 and x2 values (from another optimization technique I used), therefore I could easily run a check if the correct values were found (they were). I also knew that only the real part was relevant.
FF = find(Var(:,1)>5&Var(:,1)<6&Var(:,2)>1&Var(:,2)<2);
RealVar = Var(FF,:)
Which gave me the variables I was looking for.

Plotting a function which behaves differently over different domains in Matlab

If I have a function f(x) which is defined as
f(x) = x^2; x>0 & x<=1
= x^3; x>1 & x<2
= 2*x; elsewhere
How do I plot this in Matlab in the same graph?
I would do this without fplot :
x = 0:0.1:3;
x1 = x(x>0 & x<=1);
x2 = x(x>1 & x<2);
x3 = x(x>2);
y1 = (x1).^2;
y2 = (x2).^3;
y3 = 2*(x3);
plot([x1 x2 x3], [y1 y2 y3])
You can define a set of x values (say between 4 <= x <= 4), then apply 2*x to every value within this interval. After, search for those x values that are within the intervals of the other functions and set those values to what they should be within those intervals. As such, try something like this:
x = -4 : 0.001 : 4;
y = 2*x;
y(x > 0 & x <= 1) = x(x > 0 & x <= 1).^2;
y(x > 1 & x < 2) = x(x > 1 & x < 2).^3;
plot(x,y);
grid;
This is what I get:

minimising function of multivariable constraints Matlab

How to minimise this function please teach me the code in MATLAB
Minimize Ra = (0.237 − 0.00175v + 8.693f − 0.00159z)
subjected to 124.53 ≤ v ≤ 167.03
0.025 ≤ f ≤ 0.083
6.2 ≤ z ≤ 14.8
You are looking at a (very degenerate) linear program.
Your unknown vector x = [v; f; z], the objective coeff vector is c = [-0.00175; 8.693; -0.00159].
In your particular case, you have no equality or inequality constraints, only lower and upper bounds lb = [124.53; 0.025; 6.2] and ub = [167.03; 0.083; 14.8] respectively.
You are trying to minimize
argmin c^T x
s.t. lb <= x <= ub
Use linprog
x = linprog( c, [], [], [], [], lb, ub );
Note that the constant coefficient 0.237 is not participating in the optimization since it has no effect on the argmin.
You could use fmincon. Let's say v = x(1), f = x(2), and z = x(3) so that tehy are all in a vector. First you define a handle to your function as:
h = #(x)(0.237 - − 0.00175*x(1) + 8.693*x(2) − 0.00159*x(3))
You need to define your constraints in the form A*x ≤ b. In your example, we rewrite the constraints as both being less than some function:
v ≤ 167.03
-v ≤ -124.53
f ≤ 0.083
-f ≤ -0.025
z ≤ 14.8
-z ≤ -6.2
Now you can convert the above into matrix form A*x ≤ b:
A = [1, 0, 0;
-1, 0, 0;
0, 1, 0;
0, -1, 0;
0, 0, 1;
0, 0, -1]
b = [167.03; -124.53; 0.083; -0.025; 14.8; -6.2]
Finally, you define an initial guess x0 for your variable x, and optimize by calling fmincon as:
xOpt = fmincon(h, x0, A, b)
The initial guess can be any values that lie within your constraints, so x0 = [167; 0.08; 14] could work.
EDIT: You could also define your lower and upper bound vectors as lb = [124.53; 0.025; 6.2] and ub = [167.03; 0.083; 14.8] and call fmincon using:
xOpt = fmincon(h, x0, [], [], [], [], lb, ub)
Note: if you want to randomize your initial guess, you can use your lb and ub vectors to do so with x0 = lb + (ub - lb)*rand().
This is a bit more powerful of a tool than you need for this problem, but hey, teach a man to fish.
Well, it's very simple:
>> Min_Ra = 0.237 − 0.00175*167.03 + 8.693*0.025 − 0.00159*14.8
ans =
0.1384905
:)
(just subtract the maximum permissible amounts while adding the minimum permissible amounts)

how to plot 3d inequalities on matlab [duplicate]

This question already has answers here:
Draw 3d Inequality on Matlab
(1 answer)
matlab - plot inequality in 3d with surf
(1 answer)
Closed 1 year ago.
I want to plot a 3d region in MATLAB bounded from a set of inequalities.
For example:
0 <= x <= 1
sqrt(x) <= y <= 1
0 <= z <= 1 - y
I found a 2d example that someone has done on this site but I'm not sure how to convert that to 3d. How to plot inequalities.
Edit:
From #Tobold's help I modified the code to restrict the points that are plotted to those that are defined by all three regions, but it plots only 2 or 3 points. It looks like the points in the vectors X1, Y1 and Z1 are right but for some reason its plotting only a few. Any ideas why it is only plotting a few points from the X1, Y1 and Z1 vectors instead of all of them?
[X,Y,Z]=meshgrid(0:0.1:1,0:0.1:1,0:0.1:1); % Make a grid of points between 0 and 1
p1=0.1; p2=0.2; % Choose some parameters
X1 = (X >= 0 & X <= 1) & (Y >= sqrt(X) & Y <= 1) & (Z >= 0 & Z <= 1 - Y);
Y1 = (X >= 0 & X <= 1) & (Y >= sqrt(X) & Y <= 1) & (Z >= 0 & Z <= 1 - Y);
Z1 = (X >= 0 & X <= 1) & (Y >= sqrt(X) & Y <= 1) & (Z >= 0 & Z <= 1 - Y);
ineq1 = (X >= 0 & X <= 1) * 2;
ineq2 = (Y >= sqrt(X) & Y <= 1) * 4;
ineq3 = (Z >= 0 & Z <= 1 - Y) * 8;
all = ineq1 & ineq2 & ineq3;
colors = zeros(size(X))+ineq1+ineq2+ineq3;
scatter3(X1(:),Y1(:),Z1(:),3,colors(:)','filled')
You can do almost the same thing as in the 2d case that you linked to. Just write down your three inequalities, use a 3d meshgrid, multiply each inequality with a number from a set of three numbers that has unique subset sums (e.g. 2, 4, 8) and use scatter3:
[X,Y,Z]=meshgrid(0:0.1:1,0:0.1:1,0:0.1:1); % Make a grid of points between 0 and 1
p1=0.1; p2=0.2; % Choose some parameters
ineq1 = (X >= 0 & X <= 1) * 2;
ineq2 = (X >= sqrt(X) & Y <= 1) * 4;
ineq3 = (Z >= 0 & Z <= 1 - Y) * 8;
colors = zeros(size(X))+ineq1+ineq2+ineq3;
scatter3(X(:),Y(:),Z(:),3,colors(:),'filled')
I've been trying to figure out the same thing, and the trick is to make the size of everything not in the intersection 0. Tobold's scatter3 line uses '3' as the option for size, meaning all points will show up as point 3. This can be substituted for a matrix of equal size to X1 with the set of sizes. The easiest way to do this is just make s = 3*all:
all = ineq1 & ineq2 & ineq3;
colors = zeros(size(X))+all;
sizes = 3 * all;
scatter3(X1(:),Y1(:),Z1(:),sizes,colors(:)','filled')
That should get you just the area in the intersection.
--
edit: The color variable needs to change too. You just want the intersection, not the other inequalities.
I don't understand several things in the code that you wrote as modification of #Tobold's help. For example what are the parameters p1 and p2 doing in your code?
Anyway, The code plotting only the points of your grid satisfying all of your inequalities;
[X,Y,Z]=meshgrid(0:0.1:1,0:0.1:1,0:0.1:1);
ineq1 = (X >= 0 & X <= 1);
ineq2 = (Y >= sqrt(X) & Y <= 1);
ineq3 = (Z >= 0 & Z <= 1 - Y);
all = ineq1 & ineq2 & ineq3;
scatter3(X(all),Y(all),Z(all),'b','filled')
The result is brought in the following image.