File: [local] / OpenXM / src / asir-contrib / packages / src / nk_restriction.rr (download)
Revision 1.23, Sat May 14 06:37:43 2016 UTC (8 years ago) by nakayama
Branch: MAIN
CVS Tags: HEAD Changes since 1.22: +4 -3
lines
nk_module_gr2.rr : compute module integration, restriction.
nk_restriction.rr : import nk_module_gr2.rr
|
/*
#define DEBUG_RESTRICTION
*/
import("bfct")$
import("noro_module_syz.rr")$ /* for newsyz.module_syz() */
import("nk_module_gr2.rr")$ /* module_integration, module_restriction */
module nk_restriction;
extern NK_RESTRICTION_NOLOG;
localf version;
localf generic_bfct_and_gr;
localf initial_ideal;
localf initial_w, initial_part_w;
localf restriction;
localf max_int_root;
localf test_max_int_root;
localf gen;
localf cons_rev;
localf test_gen;
localf ord_w;
localf weyl_mul;
localf test_restriction;
localf test_restriction2;
localf test_restriction3;
localf restriction_ideal;
localf test_restriction_ideal;
localf restriction_ideal_internal;
localf test_restriction_ideal_internal;
localf test_nd_weyl_gr;
localf fourier_trans;
localf test_fourier_trans;
localf inv_fourier_trans;
localf test_inv_fourier_trans;
localf integration;
localf test_integration;
localf test_integration2;
localf test_integration3;
localf test_integration4;
localf test_integration5;
localf integration_ideal;
localf integration_ideal_internal;
localf integration_ideal_;
localf integration_ideal_internal_;
localf test_integration_ideal;
localf test_integration_ideal2;
localf test_integration_ideal5;
localf test_integration_ideal5_;
localf test_integration_ideal6;
localf test_integration_ideal7;
localf test_integration_ideal8;
localf coord_conv;
localf check_coord_conv, check_coord_conv2;
localf dummy_var;
localf ann_mul;
localf test_ann_mul, test_ann_mul2, test_ann_mul3;
localf subst_vect;
localf fano2;
localf fano3;
localf p_to_mat;
localf test_p_to_mat;
localf fano_polytope_a;
localf test_fano_polytope_a;
localf fano_polytope;
localf a_to_poly;
localf test_a_to_poly;
localf var_list;
localf test_var_list;
localf d_var;
localf int_fano;
/* inhomogeneous */
localf inhomo_part;
localf trans_inhomo, trans_inhomo_sub, pick_gen_relation, is_nonzero_const;
localf separate_var, make_elim_order_mat, make_weight_mat;
localf action_exp, action_exp_1;
localf subset, zero_inhomo;
localf integration_exp;
localf test_integration_exp;
localf time_print, time_round;
localf ost_integration_ideal, ost_integration_ideal2;
localf test_ost_integration_ideal;
localf ost_integration_exp, ost_integration_exp2;
localf ann_heaviside;
/* difference */
localf mellin_trans, mellin_trans2, inv_mellin_trans, inv_mellin_trans2;
localf mellin1, dsubst, theta, normal;
localf integration_ideal_shift;
localf inhomo_inv_mellin, inhomo_inv_mellin_sub;
localf car_func;
localf test_integration_ideal_shift, test_integration_ideal_shift2;
localf test_integration_ideal_shift3, test_integration_ideal_shift4;
localf ost_sum, test_ost_sum, test_ost_sum2;
/* parameter */
localf weyl_minipoly_by_elim, weyl_minipoly_by_elim2, weyl_minipoly_by_elim3;
def version()
{
T = "$Revision: 1.23 $";
S = str_chr(T,0," ")+1;
return sub_str(T,S,str_chr(T,S," ")-1);
}
/* source from lib/bfct generic_bfct */
/* generic b-fucntion に加えて F の <_(-W,W) についての GB を返す */
/* F : ideal, V : var list(x), DV : var list(dx), W : weight vect */
def generic_bfct_and_gr(F,V,DV,W)
{
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
if ( member(s,append(vars(F),vars(Param))) )
error("generic_bfct_and_gr : the variable 's' is reserved.");
N = length(V);
N2 = N*2;
/* If W is a list, convert it to a vector */
if ( type(W) == 4 )
W = newvect(length(W),W);
/* dp_weyl_set_weight とは...? */
dp_weyl_set_weight(W);
/* create a term order M in D<x,d> (DRL) */
M = newmat(N2,N2);
for ( J = 0; J < N2; J++ )
M[0][J] = 1;
for ( I = 1; I < N2; I++ )
M[I][N2-I] = -1;
VDV = append(V,DV);
/* create a non-term order MW in D<x,d> */
MW = newmat(N2+1,N2);
for ( J = 0; J < N; J++ )
MW[0][J] = -W[J];
for ( ; J < N2; J++ )
MW[0][J] = W[J-N];
for ( I = 1; I <= N2; I++ )
for ( J = 0; J < N2; J++ )
MW[I][J] = M[I-1][J];
/* create a homogenized term order MWH in D<x,d,h> */
MWH = newmat(N2+2,N2+1);
for ( J = 0; J <= N2; J++ )
MWH[0][J] = 1;
for ( I = 1; I <= N2+1; I++ )
for ( J = 0; J < N2; J++ )
MWH[I][J] = MW[I-1][J];
/* homogenize F */
VDVH = append(VDV,[h]);
FH = map(dp_dtop,map(dp_homo,map(dp_ptod,F,VDV)),VDVH);
/* compute a groebner basis of FH w.r.t. MWH */
dp_gr_flags(["Top",1,"NoRA",1]);
if ( !NK_RESTRICTION_NOLOG ) T0 = time(); /*tstart();*/
if ( Param && Param != [] && ::version() < 20100206 ) {
/* これ以前の nd_weyl_gr は係数体が有理関数体では動かない */
if ( !NK_RESTRICTION_NOLOG ) print("-- dp_weyl_gr_main :", 2);
GH = dp_weyl_gr_main(FH,VDVH,0,1,11);
} else {
if ( !NK_RESTRICTION_NOLOG ) print("-- nd_weyl_gr :", 2);
GH = nd_weyl_gr(FH,VDVH,0,11);
}
if ( !NK_RESTRICTION_NOLOG ) time_print(T0); /*tstop();*/
dp_gr_flags(["Top",0,"NoRA",0]);
/* dehomigenize GH */
G = map(subst,GH,h,1);
/* G is a groebner basis w.r.t. a non term order MW */
/* take the initial part w.r.t. (-W,W) */
GIN = map(initial_part,G,VDV,MW,W);
/* GIN is a groebner basis w.r.t. a term order M */
/* As -W+W=0, gr_(-W,W)(D<x,d>) = D<x,d> */
/* find b(W1*x1*d1+...+WN*xN*dN) in Id(GIN) */
for ( I = 0, T = 0; I < N; I++ )
T += W[I]*V[I]*DV[I];
if ( S0 >= 0 ) {
if ( !NK_RESTRICTION_NOLOG ) print("skip the computation of generic b-function");
return [s-S0, G];
}
if ( !NK_RESTRICTION_NOLOG ) T0 = time(); /*tstart();*/
if ( Param ) {
/* パラメータ付きは消去法で計算 */
B = weyl_minipoly_by_elim2(GIN,V,DV,Param,T);
if ( !NK_RESTRICTION_NOLOG ) print("-- weyl_minipoly_by_elim :", 2);
} else {
B = weyl_minipoly(GIN,VDV,0,T); /* M represents DRL order */
if ( !NK_RESTRICTION_NOLOG ) print("-- weyl_minipoly :", 2);
}
if ( !NK_RESTRICTION_NOLOG ) time_print(T0); /*tstop();*/
return [B, G];
}
/* source from lib/bfct generic_bfct */
/* F の <_(-W,W) についての GB とその initial part を返す */
/* F : ideal, V : var list(x), DV : var list(dx), W : weight vect */
def initial_ideal(F,V,DV,W)
{
N = length(V);
N2 = N*2;
/* If W is a list, convert it to a vector */
if ( type(W) == 4 )
W = newvect(length(W),W);
/* dp_weyl_set_weight とは...? */
dp_weyl_set_weight(W);
/* create a term order M in D<x,d> (DRL) */
M = newmat(N2,N2);
for ( J = 0; J < N2; J++ )
M[0][J] = 1;
for ( I = 1; I < N2; I++ )
M[I][N2-I] = -1;
VDV = append(V,DV);
/* create a non-term order MW in D<x,d> */
MW = newmat(N2+1,N2);
for ( J = 0; J < N; J++ )
MW[0][J] = -W[J];
for ( ; J < N2; J++ )
MW[0][J] = W[J-N];
for ( I = 1; I <= N2; I++ )
for ( J = 0; J < N2; J++ )
MW[I][J] = M[I-1][J];
/* create a homogenized term order MWH in D<x,d,h> */
MWH = newmat(N2+2,N2+1);
for ( J = 0; J <= N2; J++ )
MWH[0][J] = 1;
for ( I = 1; I <= N2+1; I++ )
for ( J = 0; J < N2; J++ )
MWH[I][J] = MW[I-1][J];
/* homogenize F */
VDVH = append(VDV,[h]);
FH = map(dp_dtop,map(dp_homo,map(dp_ptod,F,VDV)),VDVH);
/* compute a groebner basis of FH w.r.t. MWH */
dp_gr_flags(["Top",1,"NoRA",1]);
GH = dp_weyl_gr_main(FH,VDVH,0,1,11);
dp_gr_flags(["Top",0,"NoRA",0]);
/* dehomigenize GH */
G = map(subst,GH,h,1);
/* G is a groebner basis w.r.t. a non term order MW */
/* take the initial part w.r.t. (-W,W) */
GIN = map(initial_part,G,VDV,MW,W);
/* GIN is a groebner basis w.r.t. a term order M */
/* As -W+W=0, gr_(-W,W)(D<x,d>) = D<x,d> */
return [G, GIN];
}
def initial_w(B,V,W)
{
MW = make_weight_mat(W);
GB = nd_weyl_gr(B,V,0,MW);
return map(initial_part_w,GB,V,MW,W);
}
def initial_part_w(F,V,MW,W)
{
N2 = length(V);
N = N2/2;
dp_ord(MW);
DF = dp_ptod(F,V);
R = dp_hm(DF);
DF = dp_rest(DF);
E = dp_etov(R);
for ( I = 0, TW = 0; I < N2; I++ )
TW += W[I]*E[I];
RW = TW;
for ( ; DF; DF = dp_rest(DF) ) {
E = dp_etov(DF);
for ( I = 0, TW = 0; I < N2; I++ )
TW += W[I]*E[I];
if ( TW == RW )
R += dp_hm(DF);
else if ( TW < RW )
break;
else
error("initial_part : cannot happen");
}
return dp_dtop(R,V);
}
/* 消去法による最小多項式計算 (パラメータを含む場合) */
def weyl_minipoly_by_elim(GIN,V,DV,Param,T)
{
TMP_S = s; TMP_DS = ds;
SV = cons(TMP_S,V); DSV = cons(TMP_DS,DV);
DParam = map(d_var,Param);
VV = append(append(SV,Param),append(DSV,DParam));
NP = length(Param);
NV = length(V);
N = NP+NV+1;
M = make_elim_order_mat(0,N);
G = cons(TMP_S-T,GIN);
for ( K = 0; K < 2; K++ ) {
for ( I = 0; I < NV; I++ ) {
IND = 2*NV+NP+1-I-K*(NV+NP+1);
M[0][IND] = 1;
GB = nd_weyl_gr(G,VV,0,M);
G = [];
while ( GB != [] ) {
if ( member(VV[IND],vars(car(GB))) )
break;
G = cons(car(GB),G);
GB = cdr(GB);
}
G = reverse(G);
}
}
if ( !subset(vars(G),cons(TMP_S,Param)) )
error("weyl_minipoly_by_elim : invalid elimination");
if ( G == [] )
error("weyl_minipoly_by_elim : b-function does not exist");
if ( length(G) != 1 ) {
if ( !NK_RESTRICTION_NOLOG ) print(G);
G = nd_gr(G,[TMP_S],0,0);
if ( !NK_RESTRICTION_NOLOG ) print(G);
}
if ( length(G) != 1 )
error("weyl_minipoly_by_elim : invalid b-function");
return car(G);
}
/* 消去法による最小多項式計算 (パラメータを含む場合) */
def weyl_minipoly_by_elim2(GIN,V,DV,Param,T)
{
TMP_S = s; TMP_DS = ds;
SV = cons(TMP_S,V); DSV = cons(TMP_DS,DV);
DParam = map(d_var,Param);
VV = append(SV,DSV);
NP = length(Param);
NV = length(V);
N = NV+1;
M = make_elim_order_mat(0,N);
G = cons(TMP_S-T,GIN);
for ( K = 0; K < 2; K++ ) {
for ( I = 0; I < NV; I++ ) {
IND = 2*NV+1-I-K*(NV+1);
M[0][IND] = 1;
if ( Param != [] && ::version() < 20100206 )
GB = dp_weyl_gr_main(G,VV,0,0,M);
else
GB = nd_weyl_gr(G,VV,0,M);
G = [];
while ( GB != [] ) {
if ( member(VV[IND],vars(car(GB))) )
break;
G = cons(car(GB),G);
GB = cdr(GB);
}
G = reverse(G);
}
}
if ( !subset(vars(G),cons(TMP_S,Param)) )
error("weyl_minipoly_by_elim : invalid elimination");
if ( G == [] )
error("weyl_minipoly_by_elim : b-function does not exist");
if ( length(G) != 1 )
error("weyl_minipoly_by_elim : invalid b-function");
return car(G);
}
/* 消去法による最小多項式計算 (パラメータを含む場合) */
def weyl_minipoly_by_elim3(GIN,V,DV,Param,T)
{
TMP_S = s; TMP_DS = ds;
SV = cons(TMP_S,V); DSV = cons(TMP_DS,DV);
DParam = map(d_var,Param);
VV = append(append(SV,Param),append(DSV,DParam));
NP = length(Param);
NV = length(V);
N = NP+NV+1;
M = make_elim_order_mat(0,N);
G = cons(TMP_S-T,GIN);
for ( K = 0; K < 2; K++ ) {
for ( I = 0; I < NV; I++ ) {
IND = 2*NV+NP+1-I-K*(NV+NP+1);
M[0][IND] = 1;
GB = dp_weyl_gr_main(G,VV,0,0,M);
G = [];
while ( GB != [] ) {
if ( member(VV[IND],vars(car(GB))) )
break;
G = cons(car(GB),G);
GB = cdr(GB);
}
G = reverse(G);
}
}
if ( !subset(vars(G),cons(TMP_S,Param)) )
error("weyl_minipoly_by_elim : invalid elimination");
if ( G == [] )
error("weyl_minipoly_by_elim : b-function does not exist");
if ( length(G) != 1 ) {
if ( !NK_RESTRICTION_NOLOG ) print(G);
G = nd_gr(G,[TMP_S],0,0);
if ( !NK_RESTRICTION_NOLOG ) print(G);
}
if ( length(G) != 1 )
error("weyl_minipoly_by_elim : invalid b-function");
return car(G);
}
/*
* restriction module の計算([SST, Alg5.2.8])
* Id : ideal
* VL : var list (x)
* DVL: var list (dx)
* W : weight vector
* VL と長さは同じ
* W[0], ..., W[M] が正で、それ以降の要素は 0 としておく
*
* Option
* param : パラメータとみなす変数のリスト
* s0 : s0 >= 0 のとき generic b-function の計算を行わず
* s-s0 を generic b-function として計算する
*/
def restriction(Id, VL, DVL, W)
{
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
if ( !NK_RESTRICTION_NOLOG ) tstart();
Result = generic_bfct_and_gr(Id, VL, DVL, W|param=Param, s0=S0);
if ( !NK_RESTRICTION_NOLOG ) print("-- generic_bfct_and_gr :",2);
if ( !NK_RESTRICTION_NOLOG ) tstop();
BF = Result[0];
GB = Result[1];
if ( !NK_RESTRICTION_NOLOG ) tstart();
/* BF の最大整数根 S0 を取り出す */
L = fctr(BF);
BFF = L;
/* L の最初の要素は係数なので捨てる */
L = cdr(L);
N = length(L);
S0 = [];
for (I = 0; I < N; I++) {
T = L[I][0];
if ( vars(T) == [s] ) { /* パラメータは generic とする */
Root = -coef(T, 0, s) / coef(T, 1, s);
if (dn(Root) == 1) {
if (S0 == []) {
S0 = Root;
} else if (Root > S0) {
S0 = Root;
}
}
}
}
if ( !NK_RESTRICTION_NOLOG ) {
print("generic bfct : " + rtostr(BFF), 1);
print("S0 : " + rtostr(S0), 1);
}
/* b-function が非負整数根を持たない場合([SST, Cor5.2.7]) */
if (S0 == [] || S0 < 0) {
if ( IH )
S0 = 0;
else
return 0;
}
for (M = 0; M < length(W); M++)
if (W[M] <= 0)
break;
/* W の正の要素の部分だけとりだしたもの WW */
WW = newvect(M);
for (I = 0; I < M; I++)
WW[I] = W[I];
WW = vtol(WW);
/* B_{S0} の生成 */
Base = gen(WW, S0);
if ( !NK_RESTRICTION_NOLOG ) print("B_{S0} length : " + rtostr(length(Base)),1);
V = newvect(length(W), W);
MinusW = vtol(-V);
WVect = append(MinusW, W);
VarL = append(VL, DVL);
NN = length(GB);
OrderGB = newvect(NN);
for (I = 0; I < NN; I++)
OrderGB[I] = ord_w(GB[I], VarL, WVect);
Generator = [];
RGen = [];
for (I = 0; I < NN; I++) {
/*
* B_{S0 - OrderGB[I]}
* i.e. WW[0]*I[0]+...+WW[M-1]*I[M-1] <=
* S0 - OrderGB[I] なる (I[0],...,I[M-1]) の生成
*/
B = gen(WW, S0 - OrderGB[I]);
while (B != []) {
Index = car(B);
D = 1;
for (J = 0; J < M; J++)
D *= DVL[J]^Index[J];
P = weyl_mul(D, GB[I], VarL);
Q = P;
for (J = 0; J < M; J++)
P = subst(P, VL[J], 0);
if (P != 0) {
Generator = cons(P, Generator);
/* inhomogeneous part の保持 */
if ( IH ) RGen = cons(P-Q, RGen);
}
B = cdr(B);
}
}
if ( !NK_RESTRICTION_NOLOG ) {
print("-- fctr(BF) + base :", 2);
tstop();
}
if ( !IH ) return [Generator, Base];
return [Generator, Base, RGen];
}
/* F は s の多項式 */
/* ただし F は Q 上 1 次式に因数分解できるものとする */
def max_int_root(F)
{
L = fctr(F);
/* L の最初の要素は係数なので捨てる */
L = cdr(L);
N = length(L);
S0 = [];
for (I = 0; I < N; I++) {
T = L[I][0];
Root = -coef(T, 0, s) / coef(T, 1, s);
if (dn(Root) == 1) {
if (S0 == []) {
S0 = Root;
} else if (Root > S0) {
S0 = Root;
}
}
}
return S0;
}
def test_max_int_root()
{
print(max_int_root(3*(s+3)^2*(s+1)^3));
print(max_int_root((s+1/2)*(s+1/3)*(s+3)^2*(s+1)^3));
print(max_int_root((s+1/2)*(s+1/3)*(s+1/5)^2*(s+1/10)^3));
}
/*
* I[0]*W[0] + ... + I[M-1]*W[M-1] <= S0 なる
* [I[0], ..., I[M-1]] を返す
*/
def gen(W, S0)
{
if (W == [])
return [[]];
Weight = car(W);
LL = [];
for (I = 0; I <= S0 / Weight; I++) {
L = gen(cdr(W), S0 - Weight * I);
L = map(cons_rev, L, I);
LL = append(L, LL);
}
return LL;
}
/* map 適用のため */
def cons_rev(L, I)
{
return cons(I, L);
}
def test_gen()
{
print(gen([1],3));
print(gen([1,1,1],3));
print(gen([1,1,1],5));
print(gen([1,2,3],5));
}
/* from localb.rr */
def ord_w(P, VL, W)
{
if (P == 0) {
print("ord_w(0)");
return;
}
N = length(VL);
DP = dp_ptod(P, VL);
V = dp_etov(DP);
DP = dp_rest(DP);
for (Max = 0, I = 0; I < N; I++)
Max += V[I] * W[I];
while (DP != 0) {
V = dp_etov(DP);
DP = dp_rest(DP);
for (Weight = 0, I = 0; I < N; I++)
Weight += V[I] * W[I];
if (Max < Weight)
Max = Weight;
}
return Max;
}
/* from localb.rr */
def weyl_mul(P, Q, VL)
{
DP = dp_ptod(P, VL);
DQ = dp_ptod(Q, VL);
return dp_dtop(dp_weyl_mul(DP, DQ), VL);
}
/* restriction のよい計算例はないか... */
def test_restriction()
{
L = [x*dx-1, y*dy-1];
print("restriction");
R1 = restriction(L, [x,y], [dx,dy], [1,0]);
print(R1);
print("sm1.restriction");
R2 = sm1.restriction(L, [x,y], [x]);
print(R2);
}
def test_restriction2()
{
/* from [SST, p202] */
L = [dx^2, dy^2];
print("restriction");
R1 = restriction(L, [x,y], [dx,dy], [1,0]);
print(R1);
print("sm1.restriction");
R2 = sm1.restriction(L, [x,y], [x]);
print(R2);
}
def test_restriction3()
{
/* Appell F_1 */
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
L = [x*(1-x)*dx^2+y*(1-x)*dx*dy+(c-(a+b+1)*x)*dx-b*y*dy-a*b,
y*(1-y)*dy^2+x*(1-y)*dx*dy+(c-(a+bb+1)*y)*dy-bb*x*dx-a*bb];
return restriction(L,[x,y],[dx,dy],[1,0]|param=[a,b,aa,bb,c],s0=S0);
}
/*
* restriction ideal の計算 [SST, Alg5.2.12]
* Id : D-ideal
* VL : var list (x)
* DVL: var list (dx)
* W : weight vector
* VL と長さは同じ
* W[0], ..., W[M] が正で、それ以降の要素は 0 としておく
*
* Option
* param : パラメータとみなす変数のリスト
* s0 : s0 >= 0 のとき generic b-function の計算を行わず
* s-s0 を generic b-function として計算する
* ht : homo, trace-lifting のフラグ
* ht
* 0 = 00(2) 以下 : homo なし, trace なし
* 1 = 01(2) : homo なし, trace あり
* 2 = 10(2) : homo あり, trace なし default (::version() >= 20100415)
* 3 = 11(2) 以上 : homo あり, trace あり
*/
def restriction_ideal(Id, VL, DVL, W)
{
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
if ( type(HTrace=getopt(ht)) == -1 ) HTrace = 2;
if ( type(ORD=getopt(ord)) == -1 ) ORD = 0;
if ( ORD && Param )
error("The options `param' and `ord' must be used exclusively.");
L = restriction(Id, VL, DVL, W|inhomo=IH,param=Param,s0=S0);
if ( !L ) return [1];
if ( !NK_RESTRICTION_NOLOG ) tstart();
GG = restriction_ideal_internal(L, VL, DVL, W|inhomo=IH,param=Param,ht=HTrace,ord=ORD);
if ( !NK_RESTRICTION_NOLOG ) {
print("-- restriction_ideal_internal :", 2);
tstop();
}
return GG;
}
def test_restriction_ideal()
{
/* Appell F_1 */
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
L = [x*(1-x)*dx^2+y*(1-x)*dx*dy+(c-(a+b+1)*x)*dx-b*y*dy-a*b,
y*(1-y)*dy^2+x*(1-y)*dx*dy+(c-(a+bb+1)*y)*dy-bb*x*dx-a*bb];
return restriction_ideal(L,[x,y],[dx,dy],[1,0]|inhomo=IH,param=[a,b,aa,bb,c],s0=S0);
}
/* L : result of restriction */
def restriction_ideal_internal(L, VL, DVL, W)
{
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(HTrace=getopt(ht)) == -1 ) HTrace = 2;
if ( type(ORD=getopt(ord)) == -1 ) ORD = 0;
/*
* restriction module の結果をベクトル表示に直す
* Base と同じ順に dx^Base[I] の係数を I 成分に格納
* restriction の結果の Base は最後の要素が [0,...,0]
* だからベクトル表示した場合、最後の成分が 1 の係数
*/
Gen = L[0];
Base = L[1];
if ( IH ) RGen = L[2];
M = 0;
for (M = 0; M < length(W); M++)
if (W[M] <= 0)
break;
N = length(Base);
P = length(Gen);
GenV = newvect(P);
for (I = 0; I < P; I++) {
T = Gen[I];
V = newvect(N);
for (J = 0; J < N; J++) {
Exp = Base[J];
/* T の dx_1^Exp[0] .. dx_M-1^Exp[M-1] の係数 を求める */
C = T;
for (K = 0; K < M; K++) {
C = coef(C, Exp[K], DVL[K]);
}
V[J] = C;
}
GenV[I] = vtol(V);
}
#ifdef DEBUG_RESTRICTION
print("Generators :");
print(GenV);
#endif
TMP = separate_var(VL,DVL,W|param=Param,ord=ORD);
VY = TMP[0]; DVY = TMP[1]; VLY = append(VY,DVY);
VZ = TMP[2]; DVZ = TMP[3];
OrdM = TMP[4];
GenV = vtol(GenV);
if ( !IH ) {
if ( HTrace <= 0 )
G = nd_weyl_gr(GenV, VLY, 0, [1,OrdM]);
else if ( HTrace == 1 )
G = nd_weyl_gr_trace(GenV, VLY, 0, 0, [1,OrdM]);
else if ( HTrace == 2 )
G = nd_weyl_gr(GenV, VLY, 0, [1,OrdM]|homo=1);
else
G = nd_weyl_gr_trace(GenV, VLY, 1, 0, [1,OrdM]);
if ( G == []) G = [vtol(newvect(N))];
} else {
/* 生成関係式を得るために sygyzy を計算 */
/* OpenXM/src/asir-contrib/testing/noro/module_syz.rr が必要 */
VDVL = append(VL,DVL);
if ( GenV == [] ) GenV = [[0]];
SYZ = newsyz.module_syz(GenV, VLY, 1, OrdM|weyl=1);
G = SYZ[1];
QUO = SYZ[2];
DRGen = map(dp_ptod,RGen,VDVL);
RL = [];
}
/* G の元の中で、最後の成分(i.e. 1 の係数) のみ 0 でないものを取り出す */
Len = length(G);
GG = [];
for (I = 0; I < Len; I++) {
T = G[I];
for (J = 0; J < N - 1; J++)
if (T[J] != 0)
break;
if (J == N - 1 && T[N - 1] != 0) {
if ( !IH )
GG = cons(T[N - 1], GG);
else {
R = inhomo_part(T[N-1],QUO[I],DRGen,VZ,DVZ,VDVL|rest=1);
GG = cons(R[0],GG);
RL = cons(R[1],RL);
}
}
}
if ( GG == [] )
GG = [0];
#ifdef DEBUG_RESTRICTION
print("GG :");
print(GG);
#endif
if ( !IH )
return GG;
if ( RL == [] )
RL = [zero_inhomo(VZ)];
return [GG,RL];
}
def test_restriction_ideal_internal()
{
L = restriction([x*dx-1,y*dy-1],VL=[x,y],DVL=[dx,dy],W=[1,0]);
print(L);
restriction_ideal_internal(L, VL, DVL, W);
}
def test_nd_weyl_gr()
{
/* internal error
nd_weyl_gr([newvect(2,[1,x]),newvect(2,[x,y])], [x,y,dx,dy],0,[1,0]);
*/
/* invarid argument
nd_weyl_gr(newvect(2,[[1,x],[x,y]]), [x,y,dx,dy], 0, [1,0]);
*/
/* correct */
nd_weyl_gr([[1,x],[x,y]],[x,y,dx,dy],0,[1,0]);
}
/* 微分作用素 P(x,dx) を Fourier 変換したものを返す */
/* i.e. x_i -> - dx_i, dx_i -> x_i */
def fourier_trans(P, VL, DVL)
{
N = length(VL);
VLL = append(VL, DVL);
DP = dp_ptod(P, VLL);
S = 0;
VE = newvect(2 * N);
while (DP != 0) {
C = dp_hc(DP);
V = dp_etov(DP);
/* x^a -> (-1)^|a| dx^a に変換(dp で) */
M = 0;
for (I = 0; I < N; I++)
VE[I] = 0;
for (I = 0; I < N; I++) {
VE[N + I] = V[I];
M += V[I];
}
DPD = dp_vtoe(VE);
if (M % 2 == 1)
DPD = -DPD;
/* dx^a -> x^a に変換 */
for (I = 0; I < N; I++)
VE[I] = V[N + I];
for (I = 0; I < N; I++)
VE[N + I] = 0;
DPX = dp_vtoe(VE);
T = C * dp_weyl_mul(DPD, DPX);
S += T;
DP = dp_rest(DP);
}
return dp_dtop(S, VLL);
}
def test_fourier_trans()
{
print(fourier_trans(x*dx, [x], [dx]));
print(fourier_trans(x^2*dx^2, [x], [dx]));
print(fourier_trans(x*dx*y+1, [x], [dx]));
}
/* 微分作用素 P(x,dx) を Fourier 変換したものを返す */
/* i.e. x_i -> dx_i, dx_i -> - x_i */
def inv_fourier_trans(P, VL, DVL)
{
N = length(VL);
VLL = append(VL, DVL);
DP = dp_ptod(P, VLL);
S = 0;
VE = newvect(2 * N);
while (DP != 0) {
C = dp_hc(DP);
V = dp_etov(DP);
/* x^a -> dx^a に変換(dp で) */
M = 0;
for (I = 0; I < N; I++)
VE[I] = 0;
for (I = 0; I < N; I++)
VE[N + I] = V[I];
DPD = dp_vtoe(VE);
/* dx^a -> (-1)^|a| x^a に変換 */
for (I = 0; I < N; I++) {
VE[I] = V[N + I];
M += V[N + I];
}
for (I = 0; I < N; I++)
VE[N + I] = 0;
DPX = dp_vtoe(VE);
if (M % 2 == 1)
DPX = -DPX;
T = C * dp_weyl_mul(DPD, DPX);
S += T;
DP = dp_rest(DP);
}
return dp_dtop(S, VLL);
}
def test_inv_fourier_trans()
{
print(inv_fourier_trans(fourier_trans(x^2*dx^2*y+x*dx*dy+y, [x], [dx]),[x],[dx]));
}
/*
* integration module の計算([SST, Alg5.5.4])
* Id : ideal
* VL : var list (x)
* DVL: var list (dx)
* W : weight vector
* VL と長さは同じ
* W[0], ..., W[M] が正で、それ以降の要素は 0 としておく
*
* Option
* param : パラメータとみなす変数のリスト
* s0 : s0 >= 0 のとき generic b-function の計算を行わず
* s-s0 を generic b-function として計算する
*/
def integration(Id, VL, DVL, W)
{
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
for (M = 0; M < length(W); M++)
if (W[M] <= 0)
break;
VLM = newvect(M);
DVLM = newvect(M);
for (I = 0; I < M; I++) {
VLM[I] = VL[I];
DVLM[I] = DVL[I];
}
VLM = vtol(VLM);
DVLM = vtol(DVLM);
FId = map(fourier_trans, Id, VLM, DVLM);
R = restriction(FId, VL, DVL, W|inhomo=IH,param=Param, s0=S0);
if ( !R ) return 0;
#ifdef DEBUG_RESTRICTION
print("restriction of FId :");
print(R);
#endif
Generator = map(inv_fourier_trans, R[0], VLM, DVLM);
if ( !IH ) return [Generator, R[1]];
return [Generator, R[1], R[2]];
}
def test_integration()
{
/* [SST, Ex5.5.2, 5.5.6] */
/* integration of the annihilating ideal of 1/(t^2-x) w.r.t. t */
Id = [2*t*dx+dt, t*dt+2*x*dx+2];
return integration(Id, [t,x],[dt,dx],[1,0]);
}
def test_integration2()
{
/* [SST, Ex5.6.13] */
/* integration of the annihilating ideal of e^(t^3-x*t) w.r.t. t */
Id = [dt - (3*t^2-x), dx + t];
return integration(Id, [t,x],[dt,dx],[1,0]);
}
def test_integration3()
{
/* [SST, Ex5.5.9] */
/* 計算が合わない?? */
F = x^3+t1^3+t2^3;
Ann = ann(F);
Ann0 = map(subst, Ann, s, -2);
Int = integration(Ann0, [t1,t2,x],[dt1,dt2,dx],[1,1,0]);
return Int;
}
def test_integration4()
{
/* [SST, Ex5.5.16] */
/* test_integration3 と同じイデアルだが、重みベクトルが異なる */
F = x1^3+x2^3+x3^3;
Ann = ann(F);
Ann0 = map(subst, Ann, s, -2);
Int = integration(Ann0, [x1,x2,x3],[dx1,dx2,dx3],[1,2,3]);
return Int;
}
def test_integration5()
{
/* [SST, Ex5.6.4] */
G = x1*t1^2*t2+x2*t1^2*t2^2+x3*t1*t2^2+x4+x5*t1*t2;
Ann = ann(G);
/* G の bfct は s + 1 */
Ann0 = map(subst, Ann, s, -1);
Int = integration(Ann0, [t1,t2,x1,x2,x3,x4,x5],[dt1,dt2,dx1,dx2,dx3,dx4,dx5],[1,1,0,0,0,0,0]);
return Int;
}
/*
* integration ideal の計算 [SST, Alg5.5.4]
* Id : D-ideal
* VL : var list (x)
* DVL: var list (dx)
* W : weight vector
* VL と長さは同じ
* W[0], ..., W[M] が正で、それ以降の要素は 0 としておく
*
* Option
* param : パラメータとみなす変数のリスト
* s0 : s0 >= 0 のとき generic b-function の計算を行わず
* s-s0 を generic b-function として計算する
* inhomo: 0 でないとき inhomogeneous part の情報もあわせて返す
* ht : homo, trace-lifting のフラグ
* ht
* 0 = 00(2) 以下 : homo なし, trace なし
* 1 = 01(2) : homo なし, trace あり
* 2 = 10(2) : homo あり, trace なし default (::version() >= 20100415)
* 3 = 11(2) 以上 : homo あり, trace あり
*/
def integration_ideal(Id, VL, DVL, W)
{
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
if ( type(HTrace=getopt(ht)) == -1 ) HTrace = 2;
if ( type(ORD=getopt(ord)) == -1 ) ORD = 0;
if ( ORD && Param )
error("The options `param' and `ord' must be used exclusively.");
L = integration(Id, VL, DVL, W|inhomo=IH,param=Param, s0=S0);
if ( !L ) return [1];
#ifdef DEBUG_RESTRICTION
print("integration :");
print(L);
#endif
if ( !NK_RESTRICTION_NOLOG ) tstart();
GG = integration_ideal_internal(L, VL, DVL, W|inhomo=IH,param=Param,ht=HTrace, ord=ORD);
if ( !NK_RESTRICTION_NOLOG ) {
print("-- integration_ideal_internal :", 2);
tstop();
}
return GG;
}
/* L : result of integration */
def integration_ideal_internal(L, VL, DVL, W)
{
if ( type(IH=getopt(inhomo)) == -1) IH = 0;
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(HTrace=getopt(ht)) == -1 ) HTrace = 2;
if ( type(ORD=getopt(ord)) == -1 ) ORD = 0;
/*
* integration module の結果をベクトル表示に直す
* Base と同じ順に x^Base[I] の係数を I 成分に格納
* restriction の結果の Base は最後の要素が [0,...,0]
* だからベクトル表示した場合、最後の成分が 1 の係数
*/
Gen = L[0];
Base = L[1];
if ( IH ) RGen = L[2];
M = 0;
for (M = 0; M < length(W); M++)
if (W[M] <= 0)
break;
N = length(Base);
P = length(Gen);
GenV = newvect(P);
for (I = 0; I < P; I++) {
T = Gen[I];
V = newvect(N);
for (J = 0; J < N; J++) {
Exp = Base[J];
/* T の x_1^Exp[0] .. x_M-1^Exp[M-1] の係数 を求める */
C = T;
for (K = 0; K < M; K++) {
C = coef(C, Exp[K], VL[K]);
}
V[J] = C;
}
GenV[I] = vtol(V);
}
#ifdef DEBUG_RESTRICTION
print("Generators :");
print(GenV);
#endif
TMP = separate_var(VL,DVL,W|param=Param,ord=ORD);
VY = TMP[0]; DVY = TMP[1]; VLY = append(VY,DVY);
VZ = TMP[2]; DVZ = TMP[3];
OrdM = TMP[4];
GenV = vtol(GenV);
if ( !IH ) {
if ( HTrace <= 0 )
G = nd_weyl_gr(GenV, VLY, 0, [1,OrdM]);
else if ( HTrace == 1 )
G = nd_weyl_gr_trace(GenV, VLY, 0, 0, [1,OrdM]);
else if ( HTrace == 2 )
G = nd_weyl_gr(GenV, VLY, 0, [1,OrdM]|homo=1);
else
G = nd_weyl_gr_trace(GenV, VLY, 1, 0, [1,OrdM]);
if ( G == []) G = [vtol(newvect(N))];
} else {
/* 生成関係式を得るために sygyzy を計算 */
/* OpenXM/src/asir-contrib/testing/noro/module_syz.rr が必要 */
VDVL = append(VL,DVL);
if ( GenV == [] ) GenV = [[0]];
SYZ = newsyz.module_syz(GenV, VLY, 1, OrdM|weyl=1);
G = SYZ[1];
QUO = SYZ[2];
DRGen = map(dp_ptod,RGen,VDVL);
RL = [];
}
#if 0
if (ParamType != 4) {
NN = length(VL) - M;
VLY = newvect(NN * 2);
for (I = 0; I < NN; I++) {
VLY[I] = VL[I + M];
VLY[I + NN] = DVL[I + M];
}
VLY = vtol(VLY);
GenV = vtol(GenV);
G = nd_weyl_gr(GenV, VLY, 0, [1,0]);
} else {
/*
* VLY
* [x, param, dx, dparam]
*/
NN = length(VL) - M + length(Param);
VLY = newvect(NN * 2);
for (I = 0; I < length(VL) - M; I++) {
VLY[I] = VL[I + M];
VLY[I + NN] = DVL[I + M];
}
for (;I < NN; I++) {
VLY[I] = Param[I - length(VL) + M];
VLY[I + NN] = strtov("d" + rtostr(Param[I - length(VL) + M]));
}
VLY = vtol(VLY);
GenV = vtol(GenV);
/*
* OrdM
* x,param,dx,dparam
* [1, 0, 1, 0]
* [ grevlex ]
*/
OrdM = newmat(2 * NN + 2, 2 * NN);
for (I = 0; I < length(VL) - M; I++) {
OrdM[0][I] = 1;
OrdM[0][I + NN] = 1;
}
for (I = 0; I < 2 * NN; I++)
OrdM[1][I] = 1;
for (I = 0; I < 2 * NN; I++)
OrdM[I][2 * NN - 1 - I] = -1;
G = nd_weyl_gr(GenV, VLY, 0, [1,OrdM]);
}
#endif
/* G の元の中で、最後の成分(i.e. 1 の係数) のみ 0 でないものを取り出す */
Len = length(G);
GG = [];
for (I = 0; I < Len; I++) {
T = G[I];
for (J = 0; J < N - 1; J++)
if (T[J] != 0)
break;
if (J == N - 1 && T[N - 1] != 0) {
if ( !IH )
GG = cons(T[N - 1], GG);
else {
R = inhomo_part(T[N-1],QUO[I],DRGen,VZ,DVZ,VDVL);
GG = cons(R[0],GG);
RL = cons(R[1],RL);
}
}
}
if ( GG == [] )
GG = [0];
#ifdef DEBUG_RESTRICTION
print("GG :");
print(GG);
#endif
if ( !IH )
return GG;
if ( RL == [] )
RL = [zero_inhomo(DVZ)];
return [GG,RL];
}
/* nd_weyl_gr を実行せず、加群の生成元を返す */
/* 計算は完了していない */
def integration_ideal_(Id, VL, DVL, W)
{
L = integration(Id, VL, DVL, W);
LL = integration_ideal_internal_(L, VL, DVL, W);
return LL;
}
/* nd_weyl_gr を実行せず、加群の生成元を返す */
def integration_ideal_internal_(L, VL, DVL, W)
{
/*
* integration module の結果をベクトル表示に直す
* Base と同じ順に x^Base[I] の係数を I 成分に格納
* restriction の結果の Base は最後の要素が [0,...,0]
* だからベクトル表示した場合、最後の成分が 1 の係数
*/
Gen = L[0];
Base = L[1];
M = 0;
for (M = 0; M < length(W); M++)
if (W[M] <= 0)
break;
N = length(Base);
P = length(Gen);
GenV = newvect(P);
for (I = 0; I < P; I++) {
T = Gen[I];
V = newvect(N);
for (J = 0; J < N; J++) {
Exp = Base[J];
/* T の x_1^Exp[0] .. x_M-1^Exp[M-1] の係数 を求める */
C = T;
for (K = 0; K < M; K++) {
C = coef(C, Exp[K], VL[K]);
}
V[J] = C;
}
GenV[I] = vtol(V);
}
#ifdef DEBUG_RESTRICTION
print("Generators :");
print(GenV);
#endif
NN = length(VL) - M;
VLY = newvect(NN * 2);
for (I = 0; I < NN; I++) {
VLY[I] = VL[I + M];
VLY[I + NN] = DVL[I + M];
}
VLY = vtol(VLY);
GenV = vtol(GenV);
return [GenV, VLY];
}
def test_integration_ideal()
{
/* [SST, Ex5.5.2, 5.5.6] */
/* integration of the annihilating ideal of 1/(t^2-x) w.r.t. t */
Id = [2*t*dx+dt, t*dt+2*x*dx+2];
L = integration(Id, VL=[t,x],DVL=[dt,dx],W=[1,0]);
print("integration module :");
print(L);
R = integration_ideal_internal(L, VL, DVL, W);
print("integration ideal :");
print(R);
}
def test_integration_ideal2()
{
/* [SST, Ex5.5.7] */
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
F = (x1+x2*t+x3*t^2+x4*t^3)*t^2;
BF = bfct(F);
print("BF :");
print(BF);
Ann = ann(F);
Ann0 = map(subst, Ann, s, -1/5);
print("Ann(F^s)|s=(-1/5) :");
print(Ann0);
print("integration ideal :");
Int = integration_ideal(Ann0, [t,x1,x2,x3,x4],[dt,dx1,dx2,dx3,dx4],[1,0,0,0,0]|inhomo=IH);
print(Int);
}
def test_integration_ideal5()
{
/* [SST, Ex5.6.4] */
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
G = x1*t1^2*t2+x2*t1^2*t2^2+x3*t1*t2^2+x4+x5*t1*t2;
Ann = ann(G);
/* G の bfct は s + 1 */
Ann0 = map(subst, Ann, s, -1);
Int = integration_ideal(Ann0, [t1,t2,x1,x2,x3,x4,x5],[dt1,dt2,dx1,dx2,dx3,dx4,dx5],[1,1,0,0,0,0,0]|inhomo=IH);
return Int;
}
def test_integration_ideal5_()
{
/* [SST, Ex5.6.4] */
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
G = x1*t1^2*t2+x2*t1^2*t2^2+x3*t1*t2^2+x4+x5*t1*t2;
Ann = ann(G);
/* G の bfct は s + 1 */
Ann0 = map(subst, Ann, s, -1);
Int = integration_ideal_(Ann0, [t1,t2,x1,x2,x3,x4,x5],[dt1,dt2,dx1,dx2,dx3,dx4,dx5],[1,1,0,0,0,0,0]|inhomo=IH);
return Int;
}
def test_integration_ideal6()
{
/*
* Gauss hypergeometric integration
* L = ndbf.ann_n([t,1-t,1-x*t]);
* L = map(subst, L, s0, b-1, s1, c-b-1, s2, -a);
*/
if (type(IH=getopt(inhomo)) == -1) IH = 0;
if (type(S0=getopt(s0)) == -1) S0 = -1;
L = [(-x^2+x)*dx^2+((-t+1)*dt+(-a-b-1)*x+c-1)*dx-b*a,(-t+1)*x*dx+(t^2-t)*dt+(-c+2)*t+b-1,(t*x-1)*dx+a*t];
Int = integration_ideal(L,[t,x],[dt,dx],[1,0]|param=[a,b,c],s0=S0,inhomo=IH);
return Int;
}
def test_integration_ideal7()
{
/* A-hypergeometric */
/* \int (x11+x21*t)^a1 (x12+x22*t)^a2 t^c dt */
if (type(IH=getopt(inhomo)) == -1) IH = 0;
if (type(S0=getopt(s0)) == -1) S0 = -1;
L = [-x11*dx11-dx21*x21+a1,-x12*dx12-dx22*x22+a2,-t*dt+c+dx21*x21+dx22*x22,t*dx12-dx22,t*dx11-dx21,dx21*dx12-dx22*dx11];
Int = integration_ideal(L,[t,x11,x12,x21,x22],[dt,dx11,dx12,dx21,dx22],[1,0,0,0,0]|param=[a1,a2,c],s0=S0,inhomo=IH);
return Int;
}
def test_integration_ideal8()
{
ORD = getopt(ord);
F = a*x^2-2*b*x+c;
A = ann(F);
AN = map(subst,A,s,-(-p*dp-1));
MB = cons(p*F-1,AN);
V = [x,p,a,b,c];
DV = [dx,dp,da,db,dc];
W = [1,0,0,0,0];
if ( type(ORD) == -1 ) {
ORD = newmat(9,8,[[0,0,0,0,0,1,1,1],[1,1,1,1,1,1,1,1]]);
for ( I = 0; I < 7; I++ )
ORD[2+I][7-I] = -1;
}
INT = integration_ideal(MB,V,DV,W|inhomo=1,ord=ORD);
return INT;
}
/* ann_mul */
/*
* x_i --> x_i
* y_i --> x_i - y_i
* dx_i --> dx_i + dy_i
* dy_i --> - dy_i
*/
def coord_conv(P, VL1, DVL1, VL2, DVL2)
{
N = length(VL1);
for (I = 0; I < N; I++)
P = subst(P, VL2[I], VL1[I] - VL2[I]);
for (I = 0; I < N; I++)
P = subst(P, DVL2[I], -DVL2[I]);
for (I = 0; I < N; I++)
P = subst(P, DVL1[I], DVL1[I] + DVL2[I]);
return P;
}
def check_coord_conv()
{
return coord_conv((1-tt)*dtt,[t],[dt],[tt],[dtt]);
}
def check_coord_conv2()
{
return coord_conv(t*dt,[t],[dt],[tt],[dtt]);
}
/* variable a --> a_ */
def dummy_var(A)
{
return strtov(rtostr(A) + "_");
}
def ann_mul(Id1, Id2, VL, DVL)
{
if (type(Param = getopt(param)) == -1)
Param = 0;
if (type(S0 = getopt(s0)) == -1)
S0 = -1;
VLL = map(dummy_var, VL);
DVLL = map(dummy_var, DVL);
Id2 = map(subst_vect, Id2, VL, VLL);
Id2 = map(subst_vect, Id2, DVL, DVLL);
Id1 = map(coord_conv, Id1, VL, DVL, VLL, DVLL);
Id2 = map(coord_conv, Id2, VL, DVL, VLL, DVLL);
Id = append(Id1, Id2);
V = append(VLL, VL);
DV = append(DVLL, DVL);
W = newvect(length(V));
for (I = 0; I < length(V)/2; I++)
W[I] = 1;
W = vtol(W);
if ( !NK_RESTRICTION_NOLOG ) {
print([Id, V, DV, W]);
print("option:" + rtostr([Param, S0]));
}
return restriction_ideal(Id, V, DV, W|param = Param, s0 = S0);
}
def test_ann_mul()
{
return ann_mul([t*dt], [(1-t)*dt],[t],[dt]);
}
def test_ann_mul2()
{
F = x^3+y^2;
G = x+y^2;
Ann1 = map(subst, ann(F), s, -1);
Ann2 = map(subst, ann(G), s, -1);
Ann = map(subst, ann(F*G), s, -1);
AnnMul = ann_mul(Ann1, Ann2, [x,y],[dx,dy]);
return [AnnMul,Ann];
}
def test_ann_mul3()
{
/* t^{a-1} (1-t)^{c-a-1} の ann */
I12 = ndbf.ann_n([t,1-t]);
I12 = map(subst, I12, s0, a-1, s1, c-a-1);
/* I12 は C<t,z,dt,dz> のイデアルとみなすので dz も追加 */
I12 = cons(dz, I12);
print("I12 :"); print(I12);
/* e^{tz} の ann */
I3 = [dt-z,dz-t];
I123 = ann_mul(I12, I3, [t,z], [dt,dz]|param=[a,c],s0=0);
print("I12 :"); print(I12);
return integration_ideal(I123, [t,z], [dt,dz], [1,0]|param=[a,c],s0=0);
}
/* F の VL[0] に V[0], ... を代入 */
def subst_vect(F, VL, V)
{
N = length(VL);
for (I = 0; I < N; I++)
F = subst(F, VL[I], V[I]);
return F;
}
/*----------------------------------------------------------------- */
/*-------------- test data for integration ideal ------------------ */
/*----------------------------------------------------------------- */
/*
#define DEBUG_FANO
*/
/* 2 次元 Fano 多面体で頂点の座標が 0,1,-1 のいづれかのもの + 原点 */
def fano2(I)
{
Fano2 = [
[[-1,0],[0,1],[1,-1],[0,0]],
[[-1,0],[0,-1],[0,1],[1,0],[0,0]],
[[-1,0],[-1,1],[0,1],[1,-1],[0,0]],
[[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[0,0]],
[[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[0,0]]];
return Fano2[I];
}
/* 3 次元 Fano 多面体で頂点の座標が 0,1,-1 のいづれかのもの + 原点 */
def fano3(I)
{
Fano3 = [
[[-1,0,0],[0,0,1],[0,1,0],[1,-1,-1],[0,0,0]],
[[-1,0,0],[0,0,-1],[0,0,1],[0,1,1],[1,-1,-1],[0,0,0]],
[[-1,0,0],[-1,1,1],[0,0,1],[0,1,0],[1,-1,-1],[0,0,0]],
[[-1,0,0],[0,0,-1],[0,0,1],[0,1,-1],[1,-1,-1],[0,0,0]],
[[-1,0,0],[-1,0,1],[0,0,1],[0,1,0],[1,-1,-1],[0,0,0]],
[[-1,0,0],[0,-1,1],[0,0,-1],[0,0,1],[0,1,-1],[1,0,0],[0,0,0]],
[[-1,0,0],[-1,1,0],[-1,1,1],[0,0,1],[0,1,1],[1,-1,-1],[0,0,0]],
[[-1,0,0],[0,-1,1],[0,0,-1],[0,0,1],[0,1,0],[1,0,-1],[0,0,0]],
[[-1,0,0],[-1,1,1],[0,0,-1],[0,0,1],[0,1,1],[1,-1,-1],[0,0,0]],
[[-1,0,0],[-1,0,-1],[-1,1,1],[0,0,1],[0,1,0],[1,-1,-1],[0,0,0]],
[[-1,0,0],[-1,0,-1],[0,0,-1],[0,0,1],[0,1,-1],[1,-1,-1],[0,0,0]],
[[-1,0,0],[-1,1,1],[0,-1,-1],[0,0,1],[0,1,0],[1,-1,-1],[0,0,0]],
[[-1,0,0],[-1,1,1],[0,-1,-1],[0,0,-1],[0,0,1],[0,1,1],[1,-1,-1],[0,0,0]],
[[-1,0,0],[-1,1,0],[-1,1,1],[0,-1,-1],[0,0,1],[0,1,1],[1,-1,-1],[0,0,0]],
[[-1,0,0],[-1,0,1],[0,-1,1],[0,0,-1],[0,0,1],[0,1,0],[1,0,-1],[0,0,0]],
[[-1,0,0],[-1,0,1],[-1,1,1],[0,-1,0],[0,0,1],[0,1,0],[1,-1,-1],[0,0,0]],
[[-1,0,0],[-1,1,1],[1,-1,-1],[0,0,-1],[0,0,1],[0,1,1],[1,-1,-1],[1,0,0],[0,0,0]],
[[-1,0,0],[-1,0,1],[-1,1,1],[0,-1,0],[0,0,1],[0,1,0],[1,-1,-1],[1,0,-1],[0,0,0]]];
return Fano3[I];
}
/* L : 点データのリスト ex. fano2, fano3 の返り値 */
def p_to_mat(L)
{
N = length(L);
M = length(L[0]);
A = newmat(M + 1, N);
for (J = 0; J < N; J++)
A[0][J] = 1;
for (J = 0; J < N; J++)
for (I = 0; I < M; I++)
A[I + 1][J] = L[J][I];
return A;
}
def test_p_to_mat()
{
L = fano2(0);
print(L);
print(p_to_mat(L));
L = fano3(10);
print(L);
print(p_to_mat(L));
}
/* fano polytope に付随する GKZ 系の行列 A を返す */
/* D : dimension (2 or 3), I : data index (0--4(D=2), 0--17(D=3)) */
def fano_polytope_a(D, I)
{
if (D == 2) {
L = fano2(I);
} else if (D == 3) {
L = fano3(I);
} else {
print("D is 2 or 3");
return;
}
return p_to_mat(L);
}
def test_fano_polytope_a()
{
print(fano_polytope_a(2, 0));
print(fano_polytope_a(3, 11));
}
def fano_polytope(D, I)
{
A = fano_polytope_a(D, I);
P = a_to_poly(A);
return append([A], P);
}
/*
* 行列 A から多項式を生成
* p_to_mat(fano*(I)) が A
* ex. A = [[1,1,1],[-1,0,1],[0,1,-1]]
* F = x1*t1^-1 + x2*t2 + x3*t1*t2^-1
* t1*t2*F = x1*t2 x2*t1*t2^2 + x3*t1^2 <-- これを返す
*/
def a_to_poly(A)
{
M = size(A)[0];
N = size(A)[1];
XV = var_list("x", 1, N);
TV = var_list("t", 1, M-1);
S = 0;
V = newvect(M - 1);
for (J = 0; J < N; J++) {
for (I = 0; I < M - 1; I++) {
V[I] = A[I + 1][J];
V[I]++;
}
DPE = dp_vtoe(V);
E = dp_dtop(DPE, TV);
S += E * XV[J];
}
VL = append(TV, XV);
DXV = map(d_var, XV);
DTV = map(d_var, TV);
DVL = append(DTV, DXV);
return [S, VL, DVL];
}
def test_a_to_poly()
{
A = newmat(3,3,[[1,1,1],[-1,0,1],[0,1,-1]]);
print(A);
print(a_to_poly(A));
A = p_to_mat(fano3(10));
print(A);
print(a_to_poly(A));
}
def var_list(Str, From, To)
{
L = [];
for (I = From; I <= To; I++)
L = cons(strtov(Str + rtostr(I)), L);
return reverse(L);
}
def test_var_list()
{
print(var_list("a", 1, 11));
print(var_list("tt", 0, 5));
}
/* 不定元 Var に "d" を追加した不定元を生成 */
def d_var(Var)
{
return strtov("d" + rtostr(Var));
}
def int_fano(D, I)
{
L = fano_polytope(D, I);
F = L[1];
VL = L[2];
DVL = L[3];
W = newvect(length(VL));
for (I = 0; I < D; I++)
W[I] = 1;
W = vtol(W);
print("F :", 2);
print(F, 2);
tstart();
Id = ann(F);
print("-- ann :", 2);
tstop();
print("Ann F^s : ", 2);
print(Id);
#ifdef DEBUG_FANO
/* b-関数の計算が重たいので skip */
tstart();
BF = bfunction(F);
print("-- bfunction :", 2);
tstop();
print("bfct : ");
print(fctr(BF));
#endif
Id0 = map(subst, Id, s, -1);
print("Ann F^(-1) : ", 2);
print(Id0, 2);
J = integration_ideal(Id0, VL, DVL, W);
return J;
}
/**** added functions for inhomogeneous ****/
/*
* J = (I + dt_1 D + dt_2 D + ... + dt_m D) \cap D_Y
*
* Input
* TT : 積分イデアル J の生成元 (content が取れる可能性あり)
* QI : 生成関係式の係数 i.e TT = \sum QI[I]*(GenV[I]の最後の成分)
* DRGen : Rest part
* VZ : [ t_1, t_2, ..., t_m]
* DVZ : [dt_1, dt_2, ..., dt_m]
*
* Output [G,R]
* G[K] : 積分イデアル J の生成元 (content = 1)
* R[K] : [[[dt_1, ***],[dt_2, ***],...,[dt_m, ***]], 分母]
* i.e.
* G[K]-(dt_1 R[K][0][0][1] + dt_2 R[K][0][1][1]
* + ... + dt_m R[K][0][m][1])/R[K][1] \in I
*
*/
def inhomo_part(TT,QI,DRGen,VZ,DVZ,VDVL)
{
if ( type(REST=getopt(rest)) == -1 ) REST = 0;
#if 0
TMP = cont(TT);
CT = dp_hc(dp_ptod(TMP,vars(TMP)));
G = TT/CT;
#else
G = ptozp(TT);
CT = tdiv(TT,G);
#endif
DQI = map(dp_ptod,QI,VDVL);
for ( DP = 0, K = 0; K < length(DQI); K++ )
DP += dp_weyl_mul(DQI[K],DRGen[K]);
P = dp_dtop(DP,VDVL);
GCD = 1;
if ( P ) {
#if 0
TMP = cont(P);
CP = dp_hc(dp_ptod(TMP,vars(TMP)));
#else
CP = tdiv(P,ptozp(P));
#endif
GCD = igcd(CT,CP);
P /= GCD;
}
R = [];
for ( I = 0; I < length(VZ); I++ ) {
Q = subst(P,VZ[I],0);
S = sdiv(P-Q,VZ[I]);
if ( REST )
R = cons([VZ[I],S],R);
else
R = cons([DVZ[I],inv_fourier_trans(S,VZ,DVZ)],R);
P = Q;
}
if ( P )
error("inhomo_part : invalid inhomogeneous operator");
R = [reverse(R),CT/GCD];
return [G,R];
}
def trans_inhomo(P,INT,V,DV,W)
{
if ( type(ORD=getopt(ord)) == -1 ) ORD = 0;
TMP = separate_var(V,DV,W);
VX = TMP[0]; DVX = TMP[1]; VDVX = append(VX,DVX);
VY = TMP[2]; DVY = TMP[3]; VDVY = append(VY,DVY);
VDV = append(V,DV);
J = INT[0]; IH = INT[1];
IND = car(car(IH));
for ( CJ = [], CIH = []; J != []; J = cdr(J), IH =cdr(IH) ) {
A = car(IH);
CJ = cons(A[1]*car(J),CJ);
CIH = cons(A[0],CIH);
}
SYZ = newsyz.module_syz(cons(P,CJ),VDVX,1,ORD|weyl=1);
GR = pick_gen_relation(SYZ[0],VDVX);
DR = vtol(newvect(length(IND)));
CONST = car(GR);
for ( GR = cdr(GR); GR != []; GR = cdr(GR), CIH = cdr(CIH) ) {
if ( HGR = car(GR) ) {
DH = dp_ptod(HGR,VDV);
DR = trans_inhomo_sub(DH,DR,car(CIH),VDV);
}
}
RR = map(dp_dtop,DR,VDV);
for ( GCD = CONST, TR = RR; TR != []; TR =cdr(TR) ) {
if ( TT = car(TR) ) {
CC = tdiv(TT,ptozp(TT));
GCD = igcd(GCD,CC);
}
}
for ( R = []; RR != []; RR = cdr(RR), IND = cdr(IND) )
R = cons([car(car(IND)),car(RR)/GCD],R);
return [reverse(R),-CONST/GCD];
}
def trans_inhomo_sub(DH,DR,IH,VDV)
{
for ( L = []; IH != []; IH = cdr(IH), DR = cdr(DR) )
L = cons(dp_weyl_mul(DH,dp_ptod(car(IH)[1],VDV)) + car(DR),L);
return reverse(L);
}
def pick_gen_relation(GR,V)
{
for ( ; GR != []; GR = cdr(GR) )
if ( is_nonzero_const(car(GR)[0],V) )
return car(GR);
error("The input is not in integration/restriction ideal.");
}
def is_nonzero_const(A,V)
{
if ( !A )
return 0;
for ( VA = vars(A); VA != []; VA = cdr(VA) )
if ( member(car(VA),V) )
return 0;
return 1;
}
def separate_var(VL,DVL,W)
{
DUMMY = dummy_var;
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(ORD=getopt(ord)) == -1 ) ORD = 0;
if ( type(Weight=getopt(weight)) == -1 ) Weight = 0;
VY = []; DVY = [];
VZ = []; DVZ = [];
W1 = []; W2 = [];
for ( I = 0; I < length(VL); I++ ) {
if ( W[I] ) {
VZ = cons(VL[I],VZ);
DVZ = cons(DVL[I],DVZ);
W1 = cons(W[I],W1);
} else {
VY = cons(VL[I],VY);
DVY = cons(DVL[I],DVY);
W2 = cons(W[I],W2);
}
}
OrdM = ORD;
if ( !Weight )
if ( VY == [] ) {
VY = [DUMMY];
DVY = [strtov("d"+rtostr(DUMMY))];
}
if ( Param ) {
DParam =[];
for ( I = 0; I < length(Param); I++ )
DParam = cons(strtov("d"+rtostr(Param[I])),DParam);
OrdM = make_elim_order_mat(length(VY),length(Param));
DVY = append(DParam,DVY);
VY = append(reverse(Param),VY);
}
R = append(map(reverse,[VY,DVY,VZ,DVZ]),[OrdM]);
if ( Weight )
return append(R,map(reverse,[W2,W1]));
return R;
}
/* 1 行目の左から順に 1 が M 個, 0 が N 個, 1が M 個, 0 が N 個 並び,
* 下は grevlex 順を表す行列を返す
*/
def make_elim_order_mat(M,N)
{
NN = M+N;
OrdM = newmat(2*NN+1,2*NN);
for ( I = 0; I < M; I++ ) {
OrdM[0][I] = 1;
OrdM[0][I+NN] = 1;
}
for ( I = 0; I < 2*NN; I++ )
OrdM[1][I] = 1;
for ( I = 2; I < 2*NN+1 ; I++ )
OrdM[I][2*NN-I+1] = -1;
return OrdM;
}
def make_weight_mat(W)
{
N = length(W);
M = newmat(N+1,N,[W]);
for ( I = 0; I < N; I++)
M[1][I] = 1;
for ( I = 0; I < N-1; I++)
M[I+2][N-I-1] = -1;
return M;
}
/* P : a operator in D<V,DV>
* CE : C*exp(E) を表すリスト [C,E]
*
* C*exp(E) に P を左から作用させた結果を返す
*/
def action_exp(P,V,DV,CE)
{
VDV = append(V,DV);
DP = dp_ptod(P,VDV);
N = length(V);
R = 0;
for ( T = DP; T; T = dp_rest(T) )
R += action_exp_1(dp_hm(T),N,V,CE);
return [R,CE[1]];
}
def action_exp_1(M,N,V,CE)
{
C = CE[0];
E = CE[1];
CO = dp_hc(M);
EX = dp_etov(M);
for ( I = 0; I < N; I++ ) {
VI = V[I];
CO *= VI^EX[I];
DEVI = diff(E,VI);
for ( J = 0, EXI = EX[I+N]; J < EXI; J++ )
C = diff(C,VI)+C*DEVI;
}
return CO*C;
}
/* A \subset B ? */
def subset(A,B)
{
while ( A != [] ) {
if ( !member(car(A),B) )
return 0;
A = cdr(A);
}
return 1;
}
def zero_inhomo(VL)
{
R = [];
for ( I = 0; I < length(VL); I++ )
R = cons([VL[I],0],R);
R = reverse(R);
RL = [R,1];
return RL;
}
/* \int C*exp(E) dt */
def integration_exp(C,E,V,DV,W)
{
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
if ( type(HTrace=getopt(ht)) == -1 ) HTrace = 2;
Id = [];
for ( I = 0; I < length(V); I++ ) {
T = red(diff(C,V[I])/C);
NT = nm(T); DT = dn(T);
Id = cons(DT*DV[I]-NT-DT*diff(E,V[I]),Id);
}
G = integration_ideal(Id,V,DV,W|param=Param,s0=S0,inhomo=IH,ht=HTrace);
return G;
}
def test_integration_exp()
{
/* CREST GB School 演習問題 2-(c) */
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
return integration_exp(1,-t-x*t^3,[t,x],[dt,dx],[1,0]|inhomo=IH);
}
def time_print(T)
{
T1 = time();
CPU = time_round(T1[0] - T[0],4);
GC = time_round(T1[1] - T[1],4);
ESP = time_round(T1[3] - T[3],4);
P = rtostr(CPU)+"sec";
if ( GC )
P = P + " + gc : " + rtostr(GC)+ "sec";
P = P + "(" + rtostr(ESP) + "sec)";
if ( !NK_RESTRICTION_NOLOG ) print(P);
return 1;
}
def time_round(Z,N)
{
if ( Z == 0 ) return 0;
B = 10^N;
if ( Z >= B ) {
for ( I = 0; Z > B; I++, Z = deval(Z/10) );
Z = rint(Z);
Z = deval(Z*10^I);
/*
Z = deval(rint(Z));
*/
} else {
B /= 10;
for ( I = 0; Z < B; I++, Z *= 10 );
Z = rint(Z);
Z = deval(Z/10^I);
}
return Z;
}
/*
* Input
* Id : an ideal of D<t,dt,x,dx> which annihilates u(x,t)
* V : var list (t,x) : [ t_1,..., t_m, x_1,..., x_n]
* DV : var list (dt,dx) : [dt_1,...,dt_m,dx_1,...,dx_n]
* W : weight : W[I] > 0 ( I < m ), W[I] = 0 ( I >= m )
* LB : list of lower bounds [a_1,...,a_m]
* UB : list of upper bounds [b_1,...,b_m]
* a_i, b_i : number, strings "inf" or "-inf", parameter
*
* Output
* ideal J \subset D<x,dx> s.t.
* J \bullet \int_{a_1}^{b_1} ... \int_{a_m}^{b_m} u(x,t) dt = 0
*/
def ost_integration_ideal(Id,V,DV,W,LB,UB)
{
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
if ( type(HTrace=getopt(ht)) == -1 ) HTrace = 2;
if ( type(OL=getopt(ol)) == -1 ) OL = 0;
if ( (VB = vars(append(LB,UB))) != [] )
if ( Param == 0 )
Param = VB;
else
Param = append(Param,VB);
TMP = separate_var(V,DV,W);
VX = TMP[0]; DVX = TMP[1];
VY = TMP[2]; DVY = TMP[3]; VYDVY = append(VY,DVY);
M = length(VY);
WW = newvect(M);
TI = [];
DT = 1; OLL = newvect(length(VY)); /* for option ol */
while ( Id != [] ) {
T = 1;
MIN = 0; J = 0; /* for #else */
P = car(Id);
if ( OL ) {
OLL = car(OL); OL = cdr(OL);
DT = car(OLL); OLL = cdr(OLL);
}
for ( I = 0; I < M; I++ ) {
WW[I] = W[I];
MWW = -WW;
WT = append(vtol(MWW),vtol(WW));
O = ord_w(P,VYDVY,WT)-OLL[I];
WW[I] = 0;
#if 0
if ( O > 0 ) {
if ( LB[I] != "-inf" && subst(DT,VY[J],LB[J]) )
T *= (VY[I]-LB[I])^O;
if ( UB[I] != "inf" && UB[I] != "+inf" && subst(DT,VY[J],UB[J]) )
T *= (UB[I]-VY[I])^O;
}
}
#else
if ( O > 0 ) {
if ( MIN ) {
if ( O < MIN ) {
MIN = O;
J = I;
}
} else {
MIN = O;
J = I;
}
}
}
if ( LB[J] != "-inf" && subst(DT,VY[J],LB[J]) )
T *= (VY[J]-LB[J])^MIN;
if ( UB[J] != "inf" && UB[J] != "+inf" && subst(DT,VY[J],UB[J]) )
T *= (UB[J]-VY[J])^MIN;
#endif
TI = cons(T*P,TI);
Id = cdr(Id);
}
return integration_ideal(TI,V,DV,W|param=Param,s0=S0,inhomo=IH,ht=HTrace);
}
def test_ost_integration_ideal()
{
B = [dt+(3*t^2-1)*x,dx+t^3-t];
return ost_integration_ideal(B,[t,x],[dt,dx],[1,0],[0],["inf"]);
}
def ost_integration_exp(C,E,V,DV,W,LB,UB)
{
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
if ( type(HTrace=getopt(ht)) == -1 ) HTrace = 2;
Id = []; OL = [];
TMP = separate_var(V,DV,W); VY = TMP[2]; DVY = TMP[3];
for ( I = 0; I < length(V); I++ ) {
T = red(diff(C,V[I])/C);
NT = nm(T); DT = dn(T);
Id = cons(DT*DV[I]-NT-DT*diff(E,V[I]),Id);
for ( OLL = [], J = 0; J < length(VY); J++ )
OLL = cons(ord_w(DT,[VY[J],DVY[J]],[-1,1]),OLL);
OL = cons(cons(DT,reverse(OLL)),OL);
}
G = ost_integration_ideal(Id,V,DV,W,LB,UB|param=Param,s0=S0,inhomo=IH,ht=HTrace,ol=OL);
return G;
}
def ost_integration_ideal2(Id,V,DV,W,LB,UB)
{
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
if ( type(HTrace=getopt(ht)) == -1 ) HTrace = 2;
if ( !NK_RESTRICTION_NOLOG ) T = time();
L = ann_heaviside(V,DV,LB,UB);
TI = ann_mul(L,Id,V,DV); /* ann_mul.rr が必要 */
if ( !NK_RESTRICTION_NOLOG ) {
print("-- ann_mul :",2);
time_print(T);
T = time();
}
INT = integration_ideal(TI,V,DV,W|param=Param,s0=S0,inhomo=IH,ht=HTrace);
if ( !NK_RESTRICTION_NOLOG ) {
print("-- integration_ideal :",2);
time_print(T);
}
return INT;
}
def ann_heaviside(V,DV,LB,UB)
{
L = [];
for ( I = 0; I < length(LB); I++ ) {
T = 1;
if ( type(LB[I]) > 1 ) {
if ( LB[I] != "-inf" )
error("ann_heaviside: invalid lower bound.");
} else
T *= V[I]-LB[I];
if ( type(UB[I]) > 1 ) {
if ( UB[I] != "inf" && UB[I] != "+inf" )
error("ann_heaviside: invalid upper bound.");
} else
T *= V[I]-UB[I];
L = cons(T*DV[I],L);
}
for ( ; I < length(V); I++ )
L = cons(DV[I],L);
return L;
}
def ost_integration_exp2(C,E,V,DV,W,LB,UB)
{
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
if ( type(HTrace=getopt(ht)) == -1 ) HTrace = 2;
Id = [];
for ( I = 0; I < length(V); I++ ) {
T = red(diff(C,V[I])/C);
NT = nm(T); DT = dn(T);
Id = cons(DT*DV[I]-NT-DT*diff(E,V[I]),Id);
}
G = ost_integration_ideal2(Id,V,DV,W,LB,UB|param=Param,s0=S0,inhomo=IH,ht=HTrace);
return G;
}
/**** added functions for difference operators ****/
/* Mellin transform */
/* es <=> x, s+1 <=> -x*dx */
/* mellin_trans((s+1)*es,[s],[es],[x],[dx]) = -dx*x^2-x */
/* 差分作用素は常に右側にあるものとする */
def mellin_trans(F,E,EV,V,DV)
{
if ( type(Form=getopt(form)) == -1 ) Form = 0;
if ( Form )
for ( I = 0; I < length(E); I++ )
F = subst(F,E[I],E[I]+1);
F = normal(F,E,EV|right=1);
for ( I = 0; I < length(E); I ++ )
F = mellin1(F,E[I],EV[I],V[I],DV[I]);
return F;
}
def mellin_trans2(F,E,EV,V,DV)
{
return mellin_trans(F,E,EV,V,DV|form=1);
}
def mellin1(F,E,EV,V,DV)
{
R = dsubst(F,E,-V*DV-1,[V,DV]);
RR = subst(R,EV,V);
return RR;
}
def dsubst(P,X,L,XL)
{
R = 0;
LL = dp_ptod(1,XL);
DL = dp_ptod(L,XL);
for ( I = 0; I <= deg(P,X); I++ ){
C = coef(P,I,X);
SC = C*dp_dtop(LL,XL);
R += SC;
LL = dp_weyl_mul(LL,DL);
}
return R;
}
/* output: [nm,dn] dn*nm (dn は nm の左からかかる) */
def inv_mellin_trans(F,V,DV,E,EV)
{
if ( type(Form=getopt(form)) == -1 ) Form = 0;
VDV = append(V,DV);
DF = dp_ptod(F,VDV);
N = length(V);
R = 0;
while ( DF ) {
H = dp_etov(DF);
for ( C = 1, I = 0; I < N; I++ ) {
S = H[I] - H[I+N];
C *= EV[I]^S;
C *= theta(E[I],H[I+N]);
}
R += dp_hc(DF)*C;
DF = dp_rest(DF);
}
R = red(R); NM = nm(R); DN = dn(R);
if ( Form )
for ( I = 0; I < length(E); I++ )
NM = subst(NM,E[I],E[I]-1);
return [normal(NM,E,EV),dn(R)];
}
def inv_mellin_trans2(F,V,DV,E,EV)
{
return inv_mellin_trans(F,V,DV,E,EV|form=1);
}
def theta(S,N)
{
for ( R=1, I = 0; I < N; I++ )
R *= -S-1-I;
return R;
}
/* right=0: 右にある変数を差分作用素の"左"に */
/* right=1: 左にある変数を差分作用素の"右"に */
def normal(P,E,EV)
{
if ( type(Right=getopt(right)) == -1 ) Right = 0;
DP = dp_ptod(P,EV);
N = length(EV);
R = 0;
while ( DP ) {
H = dp_etov(DP);
C = dp_hc(DP);
for ( I = 0; I < N; I++ )
if ( Right )
C = subst(C,E[I],E[I]-H[I]);
else
C = subst(C,E[I],E[I]+H[I]);
R += C*dp_vtoe(H);
DP = dp_rest(DP);
}
return dp_dtop(R,EV);
}
def integration_ideal_shift(Id,V,DV,W1,E,EV,W2)
{
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
if ( type(HTrace=getopt(ht)) == -1 ) HTrace = 2;
MV = pppppppp;
for ( P = DP = [], I = 0; I < length(E); I++ ) {
P = cons(strtov(rtostr(MV)+rtostr(I+1)),P);
DP = cons(strtov("d"+rtostr(MV)+rtostr(I+1)),DP);
}
P = reverse(P); DP = reverse(DP);
MId = map(mellin_trans,Id,E,EV,P,DP);
TMP1 = separate_var(V,DV,W1|weight=1);
TMP2 = separate_var(P,DP,W2|weight=1);
NV = append(append(TMP1[2],TMP2[2]),append(TMP1[0],TMP2[0]));
NDV = append(append(TMP1[3],TMP2[3]),append(TMP1[1],TMP2[1]));
NW = append(append(TMP1[6],TMP2[6]),append(TMP1[5],TMP2[5]));
J = integration_ideal(MId,NV,NDV,NW|param=Param,s0=S0,inhomo=IH,ht=HTrace);
if ( IH ) {
IMJ = map(inv_mellin_trans,J[0],P,DP,E,EV);
return [map(car_func,IMJ),inhomo_inv_mellin(J[1],P,DP,E,EV,IMJ)];
} else
return map(car_func,map(inv_mellin_trans,J,P,DP,E,EV));
}
def inhomo_inv_mellin(IH,P,DP,E,EV,DN)
{
if ( type(Sum=getopt(sum)) == -1 ) Sum = 0;
if ( type(Form=getopt(form)) == -1 ) Form = 0;
R = [];
while ( IH != [] ) {
H = car(IH);
R = cons([map(inhomo_inv_mellin_sub,H[0],P,DP,E,EV,Sum,Form),H[1]/car(DN)[1]],R);
IH = cdr(IH);
DN = cdr(DN);
}
return reverse(R);
}
def inhomo_inv_mellin_sub(IH,P,DP,E,EV,Sum,Form)
{
F = IH[0]; L = IH[1];
if ( Sum ) {
F = car(inv_mellin_trans(F,P,DP,E,EV|form=Form))-1;
for ( I = 0; I < length(Sum) && Sum[I] > 0; I++ )
L = subst(L,P[I],P[I]-1);
}
return [F,inv_mellin_trans(L,P,DP,E,EV|form=Form)];
}
def car_func(L)
{
return car(L);
}
/* グレブナー道場 例題7.4.29 */
def test_integration_ideal_shift()
{
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
F = t*(1-t);
A = ann(F);
I = cons(es-F,A);
V = [t]; DV = [dt];
E = [s]; EV = [es];
W1 = [1];
W2 = [0];
return integration_ideal_shift(I,V,DV,W1,E,EV,W2|inhomo=IH);
}
/* グレブナー道場 問題7.4.29 */
def test_integration_ideal_shift2()
{
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
F = t1*t2*(1-t1-t2);
A = ann(F);
I = cons(es-F,A);
V = [t1,t2]; DV = [dt1,dt2];
E = [s]; EV = [es];
W1 = [1,1];
W2 = [0];
return integration_ideal_shift(I,V,DV,W1,E,EV,W2|inhomo=IH);
}
/* グレブナー道場 例題7.4.30 */
def test_integration_ideal_shift3()
{
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
/* A = ndbf.ann_n([t,1-t,1+2*t]); */
A = [2*dt*t^3+(-dt-2*s0-2*s1-2*s2)*t^2+(-dt+s0-s1+2*s2)*t+s0];
AN = map(ptozp,map(subst,A,s0,1/2,s1,1/2+n,s2,1/2));
I = cons(en-(1-t),AN);
J = integration_ideal_shift(I,[t],[dt],[1],[n],[en],[0]|inhomo=IH);
return J;
}
def test_integration_ideal_shift4()
{
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
/* A = ndbf.ann_n([t,1-t,1+2*t]); */
A = [2*dt*t^3+(-dt-2*s0-2*s1-2*s2)*t^2+(-dt+s0-s1+2*s2)*t+s0];
AN = map(ptozp,map(subst,A,s0,1/2+m,s1,1/2+n,s2,1/2));
I = append([en-(1-t),em-(t)],AN);
J = integration_ideal_shift(I,[t],[dt],[1],[n,m],[en,em],[0,0]|inhomo=IH);
return J;
}
def ost_sum(Id,E,EV,W)
{
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
if ( type(HTrace=getopt(ht)) == -1 ) HTrace = 2;
MV = pppppppp;
for ( P = DP = [], I = 0; I < length(E); I++ ) {
P = cons(strtov(rtostr(MV)+rtostr(I+1)),P);
DP = cons(strtov("d"+rtostr(MV)+rtostr(I+1)),DP);
}
P = reverse(P); DP = reverse(DP);
MId = map(mellin_trans2,Id,E,EV,P,DP);
for ( I = 0; I < length(W) && W[I] > 0; I++ )
MId = subst(MId,P[I],P[I]+1);
J = restriction_ideal(MId,P,DP,W|param=Param,s0=S0,inhomo=IH,ht=HTrace);
if ( IH ) {
IMJ = map(inv_mellin_trans2,J[0],P,DP,E,EV);
return [map(car_func,IMJ),inhomo_inv_mellin(J[1],P,DP,E,EV,IMJ|sum=W,form=1)];
} else
return map(car_func,map(inv_mellin_trans2,J,P,DP,E,EV));
}
def test_ost_sum()
{
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
if ( type(HTrace=getopt(ht)) == -1 ) HTrace = 2;
IN = [(m1+1-n1)*em1-(m1+1),(m2+1-n+n1)*em2-(m2+1),(n1+1)*(m2-n+n1+1)*en1-(m1-n1)*(n-n1)];
I = subst(IN,n,10);
E = [n1,m1,m2];
EV = [en1,em1,em2];
W = [1,0,0];
R = ost_sum(I,E,EV,W|param=Param,s0=S0,inhomo=IH,ht=HTrace);
return R;
}
/* ost ex. 6.2 */
def test_ost_sum2()
{
if ( type(Param=getopt(param)) == -1 ) Param = 0;
if ( type(S0=getopt(s0)) == -1 ) S0 = -1;
if ( type(IH=getopt(inhomo)) == -1 ) IH = 0;
if ( type(HTrace=getopt(ht)) == -1 ) HTrace = 2;
I = [(n-k+1)*en-(n+1),(k+1)*ek-(n-k)];
E = [k,n];
EV = [ek,en];
W = [1,0];
R = ost_sum(I,E,EV,W|param=Param,s0=S0,inhomo=IH,ht=HTrace);
return R;
}
endmodule$
end$