maxima (macsyma): KKT conditions - maxima

I fancy using maxima to explore a certain quadratic problem
with linear constraints and inequalities.
Namely, I have the following set of maxima-instructions, spelling the KKT constraints:
f(a11,a12,a13,a21,a22,a23,a31,a32,a33):=(1-a11)**2*(1-q1)*q1+a12**2*(1-q2)*q2+a13*(1-q3)*q3+a21*(1-q1)*q1+(1-a22)**2*(1-q2)*q2+a23**2*(1-q3)*q3+a31**2*(1-q1)*q1+a32**2*(1-q2)*q2+(1-a33)**2*(1-q3)*q3;
F:f(a11,a12,a13,a21,a22,a23,a31,a32,a33);
g1(a11,a12,a13,a21,a22,a23,a31,a32,a33):=(q1*a11+q2*a12+q3*a13)-q1;
G1:g1(a11,a12,a13,a21,a22,a23,a31,a32,a33);
g2(a11,a12,a13,a21,a22,a23,a31,a32,a33):=(q1*a21+q2*a22+q3*a23)-q2;
G2:g2(a11,a12,a13,a21,a22,a23,a31,a32,a33);
h1(a11,a12,a13,a21,a22,a23,a31,a32,a33):=a11+a21+a31-1;
H1:h1(a11,a12,a13,a21,a22,a23,a31,a32,a33);
h2(a11,a12,a13,a21,a22,a23,a31,a32,a33):=a12+a22+a32-1;
H2:h2(a11,a12,a13,a21,a22,a23,a31,a32,a33);
h3(a11,a12,a13,a21,a22,a23,a31,a32,a33):=a13+a23+a33-1;
H3:h3(a11,a12,a13,a21,a22,a23,a31,a32,a33);
KKT(a11,a12,a13,a21,a22,a23,a31,a32,a33,lambda1,lambda2,lambda3,lambda4,lambda5,mu11,mu12,mu13,mu21,mu22,mu23,mu31,mu32,mu33):=F+lambda1*G1+lambda2*G2+lambda3*H1+lambda4*H2+lambda5*H3-mu11*a11-mu12*a12-mu13*a13-mu21*a21-mu22*a22-mu23*a23-mu31*a31-mu32*a32-mu33*a33;
kkt:KKT(a11,a12,a13,a21,a22,a23,a31,a32,a33,lambda1,lambda2,lambda3,lambda4,lambda5,mu11,mu12,mu13,mu21,mu22,mu23,mu31,mu32,mu33);
gradF : jacobian([kkt],[a11,a12,a13,a21,a22,a23,a31,a32,a33,lambda1,lambda2,lambda3,lambda4,lambda5,mu11,mu12,mu13,mu21,mu22,mu23,mu31,mu32,mu33])[1];
orthogonality_constraints : [mu11*a11 = 0, mu12*a12 = 0, mu13*a13 = 0, mu21*a21 = 0, mu22*a22 = 0, mu23*a23 = 0, mu31*a31 = 0, mu32*a32 = 0, mu33*a33 = 0];
Here, we have 9 "original" variables a11,a12,...,a33, and 2+3 = 5 constraints expressed as G1,G2,H1,H2,H3 in the above piece of code.
We would like to impose non-negativity conditions on a11,a12,...,a33,
and therefore I would like to write something like
solve([gradF,G1,G2,H1,H2,H3,orthogonality_constraints],[a11,...,a33,lambda1,...,lambda5,mu11,...,mu33]).
However, orthogonality_constraints needs to somehow be "unwrapped", I guess, before putting it inside the first argument of solve(). Same for gradF.
How to do this?

Maybe flatten
e: [gradF,G1,G2,H1,H2,H3,orthogonality_constraints] $
e: flatten(e) $
solve(e, [...]);
From ?flatten;
Applied to a list, 'flatten' gathers all list elements that are
lists.
(%i1) flatten ([a, b, [c, [d, e], f], [[g, h]], i, j]);
(%o1) [a, b, c, d, e, f, g, h, i, j]

Related

Z3 - how to count matches?

I have a finite set of pairs of type (int a, int b). The exact values of the pairs are explicitly present in the knowledge base. For example it could be represented by a function (int a, int b) -> (bool exists) which is fully defined on a finite domain.
I would like to write a function f with signature (int b) -> (int count), representing the number of pairs containing the specified b value as its second member. I would like to do this in z3 python, though it would also be useful to know how to do this in the z3 language
For example, my pairs could be:
(0, 0)
(0, 1)
(1, 1)
(1, 2)
(2, 1)
then f(0) = 1, f(1) = 3, f(2) = 1
This is a bit of an odd thing to do in z3: If the exact values of the pairs are in your knowledge base, then why do you need an SMT solver? You can just search and count using your regular programming techniques, whichever language you are in.
But perhaps you have some other constraints that come into play, and want a generic answer. Here's how one would code this problem in z3py:
from z3 import *
pairs = [(0, 0), (0, 1), (1, 1), (1, 2), (2, 1)]
def count(snd):
return sum([If(snd == p[1], 1, 0) for p in pairs])
s = Solver()
searchFor = Int('searchFor')
result = Int('result')
s.add(Or(*[searchFor == d[0] for d in pairs]))
s.add(result == count(searchFor))
while s.check() == sat:
m = s.model()
print("f(" + str(m[searchFor]) + ") = " + str(m[result]))
s.add(searchFor != m[searchFor])
When run, this prints:
f(0) = 1
f(1) = 3
f(2) = 1
as you predicted.
Again; if your pairs are exactly known (i.e., they are concrete numbers), don't use z3 for this problem: Simply write a program to count as needed. If the database values, however, are not necessarily concrete but have other constraints, then above would be the way to go.
To find out how this is coded in SMTLib (the native language z3 speaks), you can insert print(s.sexpr()) in the program before the while loop starts. That's one way. Of course, if you were writing this by hand, you might want to code it differently in SMTLib; but I'd strongly recommend sticking to higher-level languages instead of SMTLib as it tends to be hard to read/write for anyone except machines.

Z3py how to solve a problem with many possible path (k out of n potential actions, order matters) efficiently

I am trying to solve a problem that consists of n actions (n >= 8). A path consists k (k == 4 for now) actions. I would like to check if there exists any path, which satisfies the set of constraints I defined.
I have made two attempts to solve this problem:
Attempt 1: Brute force, try all permutations
Attempt 2: Code a path selection matrix M [k x n], such that each row contains one and only one element greater than 0, and all other elements equal to 0.
For instance if k == 2, n == 2, M = [[0.9, 0], [0, 0.7]] represents perform action 1 first, then action 2.
Then my state transition was coded as:
S1 = a2(a1(S0, M[1][1]), M[1][2]) = a2(a1(S0, 0.9), 0)
S2 = a2(a1(S1, M[2][1]), M[2][2]) = a2(a1(S1, 0), 0.7)
Note: I made sure that S == a(S,0), so that in each step only one action is executed.
Then constraints were checked on S2
I was hoping this to be faster than the permutation way of doing it. Unfortunately, this turns out to be slower. Just wondering if there is any better way to solve this problem?
Code:
_path = [[Real(f'step_{_i}_action_{_j}') for _j in range(len(actions))] for _i in range(number_of_steps)]
_states: List[State] = [self.s0]
for _i in range(number_of_steps):
_new_state = copy.deepcopy(_states[-1])
for _a, _p in zip(actions, _path[_i]):
self.solver.add(_a.constraints(_states[-1], _p))
_new_state = _a.execute(_new_state, _p)
_states.append(_new_state)

z3 Solver and solve give different results

I have been experimenting with z3 (version '4.8.7' obtained through pip3) and found this (apparent) discrepancy.
t, s0, s, u, a, v = Reals('t s0 s u a v')
equations = [v == u + a*t, s == s0 + u*t + a*t**2/2,
v**2 - u**2 == 2*a*s]
problem = [t == 10, s0 == 0, u == 0, a == 9.81]
solve(equations+problem)
This gives the correct output for s:
[a = 981/100, u = 0, s0 = 0, t = 10, s = 981/2, v = 981/10]
But when I use the Solver, the result is different:
solver = Solver()
solver.check(equations+problem)
solver.model()
This gives a wrong output for s, though it gets v right.
[t = 10, u = 0, s0 = 0, s = 0, a = 981/100, v = 981/10]
s should be (1/2) * (981/100) * 100 which is the result in solve.
Am I missing something obvious in z3's Solver or is this a bug? Thank you.
The issue here is that the argument to solver.check are extra assumptions the solver can make as it solves the constraints, not the actual constraints to check. See the documentation here: https://z3prover.github.io/api/html/z3py_8py_source.html#l06628
The correct call would be:
solver = Solver()
solver.add(equations+problem)
print solver.check()
print solver.model()
that is, you add the constraints, and then call check with no arguments. This would match what solve does. The argument to check are used if you want to check validity under some extra assumptions only.

Resultant weight vector has same values in SAS/IML

I'm trying to create a binary perceptron classifier using SAS to develop my skills with SAS. The data has been cleaned and split into training and test sets. Due to my inexperience, I expanded the label vector into a table of seven identical columns to correspond to the seven weights to make the calculations more straightforward, at least, given my limited experience this seemed to be a usable method. Anyway, I run the following:
PROC IML;
W = {0, 0, 0, 0, 0, 0, 0};
USE Work.X_train;
XVarNames = {"Pclass" "Sex" "Age" "FamSize" "EmbC" "EmbQ" "EmbS"};
READ ALL VAR XVarNames INTO X_trn;
USE Work.y_train;
YVarNames = {"S1" "S2" "S3" "S4" "S5" "S6" "S7"};
READ ALL VAR YVarNames INTO y_trn;
DO i = 1 to 668;
IF W`*X_trn[i] > 0 THEN Z = {1, 1, 1, 1, 1, 1, 1};
ELSE Z = {0, 0, 0, 0, 0, 0, 0};
W = W+(y_trn[i]`-Z)#X_trn[i]`;
END;
PRINT W;
RUN;
and the result is a column vector with seven entries each having value -2.373. The particular value isn't important, but clearly, a weight vector that is comprised of identical values is not useful. The question then is, what error in the code am I making that is producing this result?
My intuition is that something with how I am trying to call each row of observations for X_trn and y_trn into the equation is resulting in this error. Otherwise, it might be due to the matrix arithmetic in the W = line, but the orientation of all of the vectors seems to be appropriate.

Prolog print value as result instead of true

I need to write a program, which returns a new list from a given list with following criteria.
If list member is negative or 0 it should and that value 3 times to new list. If member is positive it should add value 2 times for that list.
For example :
goal: dt([-3,2,0],R).
R = [-3,-3,-3,2,2,0,0,0].
I have written following code and it works fine for me, but it returns true as result instead of R = [some_values]
My code :
dt([],R):- write(R). % end print new list
dt([X|Tail],R):- X =< 0, addNegavite(Tail,X,R). % add 3 negatives or 0
dt([X|Tail],R):- X > 0, addPositive(Tail,X,R). % add 2 positives
addNegavite(Tail,X,R):- append([X,X,X],R,Z), dt(Tail, Z).
addPositive(Tail,X,R):- append([X,X],R,Z), dt(Tail, Z).
Maybe someone know how to make it print R = [] instead of true.
Your code prepares the value of R as it goes down the recursing chain top-to-bottom, treating the value passed in as the initial list. Calling dt/2 with an empty list produces the desired output:
:- dt([-3,2,0],[]).
Demo #1 - Note the reversed order
This is, however, an unusual way of doing things in Prolog: typically, R is your return value, produced in the other way around, when the base case services the "empty list" situation, and the rest of the rules grow the result from that empty list:
dt([],[]). % Base case: empty list produces an empty list
dt([X|Like],R):- X =< 0, addNegavite(Like,X,R).
dt([X|Like],R):- X > 0, addPositive(Like,X,R).
% The two remaining rules do the tail first, then append:
addNegavite(Like,X,R):- dt(Like, Z), append([X,X,X], Z, R).
addPositive(Like,X,R):- dt(Like, Z), append([X,X], Z, R).
Demo #2
Why do you call write inside your clauses?
Better don't have side-effects in your clauses:
dt([], []).
dt([N|NS], [N,N,N|MS]) :-
N =< 0,
dt(NS, MS).
dt([N|NS], [N,N|MS]) :-
N > 0,
dt(NS, MS).
That will work:
?- dt([-3,2,0], R).
R = [-3, -3, -3, 2, 2, 0, 0, 0] .
A further advantage of not invoking functions with side-effects in clauses is that the reverse works, too:
?- dt(R, [-3, -3, -3, 2, 2, 0, 0, 0]).
R = [-3, 2, 0] .
Of cause you can invoke write outside of your clauses:
?- dt([-3,2,0], R), write(R).
[-3,-3,-3,2,2,0,0,0]
R = [-3, -3, -3, 2, 2, 0, 0, 0] .

Resources