//楕円曲線の足し算。 Ell:=(x,y)->y^2-x^3-p *x-q; //楕円曲線 Eの定義方程式 //P1(x1,y1),P2(x2,y2) は E の点 (次のf1,f2は0) f1:=Ell(x1,y1); f2:=Ell(x2,y2); // P1,P2 と同一直線上にある E の点を求めよう。 g:=Ell(x1+k*(x2-x1),y1+k*(y2-y1)); B:=groebner::gbasis([f1,f2]); g1:=groebner::normalf(g,B); g2:=collect(g1,VARS); // g2 は k,k-1 を因子に持つ。それで割ったのが g3 g3:=normal(expand(g2/(k*(k-1)))); //g3 は k の一次式なので、その根は次のように見つけられる。 k1:=-coeff(g3,k,0)/coeff(g3,k,1); // k1 を kに代入し、yの符号を変えたのが P1とP2 の和 x3:=(x1+k1*(x2-x1)); y3:=-(y1+k1*(y2-y1)); // 若干整理しておく xx3:=normal(x3); yy3:=normal(y3); //実際に (xx3,yy3) が E の上に乗っているかチェック。 groebner::normalf(numer(Ell(xx3,yy3)),B); //答え //xx3:= // -(3*q*x1-3*q*x2-2*x1*y1*y2+2*x2*y1*y2+p*x1^2-p*x2^2-x1*y2^2+x2*y1^2) // /(p*x1-p*x2-y1^2+y2^2-3*x1*x2^2+3*x1^2*x2); // yy3:= // (3*q*y1-3*q*y2+p*x1*y1-2*p*x1*y2+2*p*x2*y1-p*x2*y2 // +y1*y2^2-y1^2*y2+3*x1*x2^2*y1-3*x1^2*x2*y2) // / (p*x1 - p*x2 - y1^2 + y2^2 - 3*x1*x2^2 + 3*x1^2*x2)