動かない式を動かす(nnsolve その4)
まず,次をご覧ください.
(%i1) f:((x-1/x)^2+(y^2-4*y+5)^3+(z+1)^2/z^4<=1)%and(x<0); 2 (z + 1) 2 3 1 2 (%o1) (x < 0) %and (-------- + (y - 4 y + 5) + (x - -) <= 1) 4 x z
人間が見るとバレバレですが,ストレートな qepmax では
(%i2) qe([],f); 2 6 4 2 5 4 2 4 4 (%o2) (x < 0) %and (z < 0) %and (x y z - 12 x y z + 63 x y z 2 3 4 2 2 4 2 4 4 4 2 4 4 2 2 - 184 x y z + 315 x y z - 300 x y z + x z + 122 x z + z + x z 2 2 + 2 x z + x = 0)
までです.
一方,nnsolve では
(%i3) nnsolve(f); (%o3) (x + 1 = 0) %and (y - 2 = 0) %and (z + 1 = 0)
のように解けます.
より端的な例は
(%i6) qe([],a^2+b^2+c^2+d^2=0); 2 2 2 2 (%o6) d + c + b + a = 0 (%i7) nnsolve(a^2+b^2+c^2+d^2=0); (%o7) (a = 0) %and (b = 0) %and (c = 0) %and (d = 0)
といったものです.
こうした「動かない式を動かす」ために作ったのが ncond です.
ncond(f):=(f)%and( substpart("%and",map(lambda([q],qe(q,f)), fullmap(lambda([x],[E,x]), delete([],full_listify(powerset(setify(listofvars(f))))))),0))$
これは,所謂,必要条件を付加する関数で
(%i8) ncond(a^2+b^2+c^2+d^2=0); 2 2 2 2 (%o8) (a = 0) %and (b = 0) %and (b + a = 0) %and (c = 0) %and (c + a = 0) 2 2 2 2 2 2 2 %and (c + b = 0) %and (c + b + a = 0) %and (d = 0) %and (d + a = 0) 2 2 2 2 2 2 2 %and (d + b = 0) %and (d + b + a = 0) %and (d + c = 0) 2 2 2 2 2 2 2 2 2 2 %and (d + c + a = 0) %and (d + c + b = 0) %and (d + c + b + a = 0) (%i9) nns(qe([],%)); (%o9) (a = 0) %and (b = 0) %and (c = 0) %and (d = 0)
(%i10) ncond(f); (%o10) (x < 0) %and (x + 1 = 0) %and (y - 2 = 0) 2 6 2 5 2 4 2 3 2 2 2 4 %and (x y - 12 x y + 63 x y - 184 x y + 315 x y - 300 x y + x 2 + 122 x + 1 = 0) %and (z < 0) %and (z + 1 = 0) 4 4 2 4 4 2 2 2 2 %and (x z - 2 x z + z + x z + 2 x z + x = 0) 6 4 5 4 4 4 3 4 2 4 4 4 %and (y z - 12 y z + 63 y z - 184 y z + 315 y z - 300 y z + 124 z 2 2 (z + 1) 2 3 1 2 + z + 2 z + 1 = 0) %and (-------- + (y - 4 y + 5) + (x - -) <= 1) 4 x z (%i11) nns(qe([],%)); (%o11) (x + 1 = 0) %and (y - 2 = 0) %and (z + 1 = 0)
となります.