У меня проблема, когда есть каноническое решение, и любое вращение и зеркалирование (по оси) - еще одно решение. Чтобы избежать проблемы множественного решения из-за поворота, я установил ограничения, которые векторы должны быть выровнены с осью, когда это возможно. «Зеркальные» решения - вот моя проблема. В принципе, некоторые значения могут иметь положительное решение или отрицательное решение. Это дает мне 2^d
решение проблемы с размером d
. Я пытаюсь использовать assume
и фиксировать некоторые значения как всегда положительные, что должно решить проблему, но solve
все еще создает отрицательные решения.Избегайте некоторых решений в Maxima
Это мой код до сих пор:
/* A parameter w0 in (0,1] */
assume(w0>=0);
assume(w0<1);
d:2$
/* d+1 extra points, the is one at x=0, for a total fo d+2 points */
s:d+1$
/* The unknown are w (weights of the first component) and x_S vectors of dimension d */
v:append([w1],makelist(x[i-s*floor(i/s)+1,floor(i/s)+1],i,0,d*s-1));
/* The different constraints */
e:append(
/* The sum of weights is 1 */
[w0+s*w1-1=0],
/* Some of the components are 0 to be aligned with the axis */
flatten(makelist(makelist(x[i,j]=0,j,i+1,d),i,1,s-1)),
/* The mean is 0 */
makelist(sum(x[i,j],i,1,s)=0,j,1,d),
/* All vectors have length squared of x[1,1]^2, x[1,:] is skipped as only its first component is non-zero*/
makelist(sum(x[i,j]^2,j,1,d)-x[1,1]^2=0,i,2,s),
/* The diagonal of the covariance matrix is 1, w0*0 +w1*sum(x_i^2)=1*/
makelist(w1*sum(x[i,j]^2,i,1,s)-1=0,j,1,d),
/* The off-diagonal elements are 0. The dependancy on w1 can be eliminated since the equation is =0. */
flatten(makelist(makelist(sum(x[i,jj]*x[i,jj+j],i,1,s)=0,j,1,d-jj),jj,1,d-1))
);
/* THIS IS NOT WORKING AS I EXPECTED, I WANT SOLUTION ONLY WITH x[i,i]>0 */
assume(x[1,1]>0,x[2,2]>0);
solution:solve(e,v)$
number_solutions=length(solution);
Есть ли способ заставить solve
исследовать только некоторые решения этой проблемы?
РЕШЕНИЕ: После комментария Роберта, я смог получить «каноническое» решение следующим образом:
check_canonical(sol):=block([],
/* Extract the expression x[i,i]=... */
diag_expr0:makelist(sublist(sol,lambda([e],(if lhs(e)=x[i,i] then true else false))),i,1,d),
diag_expr1:flatten(diag_expr0),
/* Get the right hand side */
diag_expr2:makelist(rhs(diag_expr1[i]),i,1,d),
/* Check for the rhs to be positive */
pos_diag:sublist(diag_expr2,lambda([e],if e>0 then true else false)),
/* If all the elelment are positive, then this is a canonical solution */
if length(pos_diag)=d then true else false
)$
canonical_solution:flatten(sublist(solutions,check_canonical));
Я не эксперт по Максиму, но он работает, хотя я думаю, что было бы более интересно избегать изучения решений, которые не отвечают определенным критериям.