留数を計算するアルゴリズム

Higher residueについて眺めていて、多変数留数を計算するアルゴリズムを調べようと思った
Higher Residuesとその応用 (微分方程式の超局所解析)
http://repository.kulib.kyoto-u.ac.jp/dspace/handle/2433/102684


#Higher residueを理解したい動機は、以下のあたり
Descendants constructed from matter fields in topological Landau-Ginzburg theories coupled to topological gravity
http://arxiv.org/abs/hep-th/9211090

Topological Strings, Flat Coordinates and Gravitational Descendants
http://arxiv.org/abs/hep-th/9302048



[一変数留数の場合]
以下、基本的には、有理数関数の場合を想定する。一変数の留数の場合は、部分分数分解してやれば、原理的には気合いで何とかなるはずではある。そうはいっても、コンピュータ上では、普通、有理数係数でやるから例えば、h(z)/(z^3+z+1)とかなってると、因数分解がめんどいとか、細かい問題はある


一応、一変数の場合のアルゴリズムの解説は、以下にあって、
有理関数のローラン展開アルゴリズムと代数的局所コホモロジ.
http://repository.kulib.kyoto-u.ac.jp/dspace/handle/2433/25926

高速留数計算アルゴリズム
http://repository.kulib.kyoto-u.ac.jp/dspace/handle/2433/47838

一変数留数計算アルゴリズムについて
http://repository.kulib.kyoto-u.ac.jp/dspace/handle/2433/58572

D-加群を用いた留数値計算アルゴリズムの局所化
http://www.jssac.org/Editor/Suushiki/V07/No3/V7N3_102.pdf


現在のRisa/Asirには、これを実装したのだと思われるtaji_alc.rrがデフォルトで配布されている
1変数代数的局所コホモロジー類用パッケージ taji_alc
http://www.math.kobe-u.ac.jp/OpenXM/Current/doc/asir-contrib/ja/taji_alc-html/taji_alc-ja.html



[多変数留数のアウトライン]
多変数の場合は、$n$変数多項式の組$f_1, \cdots , f_n$に対して
\frac{1}{(2 \pi i)^n} \int \frac{h(z_1 , \cdots , z_n)dz_1 \cdots dz_n}{f_1(\mathbf{z}) \cdots f_n(\mathbf{z})}
という形の積分で、多変数留数が定義される。但し、f_1= ... = f_n=0の解集合は0次元で、hは、その解の適当な近傍で正則とする(積分は、あるn次元サイクル上で行う)。留数(local residue)は、f_1, ... , f_nの各共通零点に対して定義される。代数的に定義されたGrothendieck留数というのもあって、上の解析的な留数と一致することが証明されているっぽい(けど、わたしは、証明を知らない)。留数値は、f_1= ... = f_n=0の解集合の各点で定義されることから、f_1, ... , f_nの積が等しくても、留数は異なる値を取りうる


多変数の場合でも、基本になるのは、f_i = (z_i - a_i)の形で、一般に、$f_{i} = (z_{i} - a_{i})^{n_i}$の時、Cauchyの留数公式の多変数版が成立する。f_1= ... = f_n=0の解集合が0次元であるかどうかは、グレブナー基底を使って容易に判定できるし、解がどこにあるかも、イデアルの準素分解によって探すことができる(Risa/Asirでは、primdec.rrをロードして、primadecとかを使えばいい)。けど、多変数の場合は、一変数の場合より厄介なことが起こる。例えば、2次元で、f_1(x,y)=xy , f_2(x,y)=x+yという形の場合、f_1=f_2=0の解は、(x,y)=(0,0)のみであるけど、留数値の計算は、Cauchyの留数公式に頼ることはできない


これを補うために、transformation lawと呼ばれる便利な定理が知られていて、
 g_j = \sum A_{ij}f_i
という形の関係式($A_{ij}$は多項式)で結ばれている多項式の組$f_1 , \cdots , f_n$と$g_1 , \cdots , g_n$が共に、共通零点が0次元になってるとき、
Res(\frac{h d\mathbf{z}}{f_1 \cdots f_n}) = Res(\frac{h \cdot \det(A) d\mathbf{z}}{g_1 \cdots g_n})
が成り立つ。但し、Resは、global residueで、全てのlocal residueの和。local residueが分からなくても、例えば、完全交叉Artin代数に、Gorenstein環/Frobenius代数の構造を入れる時なんかは、global residueを使うので、local residueは分からなくてもいいという状況はある。上のhigher residueも、その一般化なので、local residueは要らんのだと思う。transformation lawの証明は、やっぱり、わたしは知らない


transformation lawの例として、f_1(x,y) = xy , f_2(x,y)=x+yの場合を考えると
x^2 = -1 * f_1 + x * f_2
y^2 = -1 * f_2 + y * f_2
とかやると、Cauchyの留数公式が使える形に持ちこめる。とはいえ、こういう変換を直接見つけるのは、通常結構しんどい



[多変数のglobal residueを計算するアルゴリズム]
多変数のglobal residueを計算するアルゴリズムは、以下の論文がある
Computing Multidimensional Residues
http://arxiv.org/abs/alg-geom/9404011


アルゴリズムそのものは、17ページに書いてあって、Algorithm(3.1)というのは、$f_1 , \cdots f_n$がある重み付き順序に関するグレブナー基底になってる時のみ使えるアルゴリズム。例えば、f_1=xy , f_2=x+yは、どんな項順序を持ってきても、グレブナー基底にはなってない。グレブナー基底になってない(一般の場合)を扱うのが、Algorithm(3.2)で、これの言ってることは、Buchbergerアルゴリズムの一回のループで、イデアルの生成元$p_1 \cdots , p_n$から、新しい生成元$q_1 , \cdots , q_m$を得た時、注意深く見ると$q_j = \sum A_{ij} p_i$という関係を満たす多項式$A_{ij}$が存在している。これを繰り返してグレブナー基底に至るわけだから、transformation lawを適用して留数の計算ができる(グレブナー基底の個数が、丁度n個になる理由は、イデアルの0次元性判定とか思い出せば分かる)


Algorithm(3.2)は、Buchbergerのアルゴリズムを実装する必要があるのだけど、Risa/AsirでBuchbergerって車輪の再発明ってレベルじゃない感じなので、とりあえず放置して、Algorithm(3.1)だけ実装した。(3.2)は、気が向いたら、そのうちやろうと思う。まぁ、論文にも書いてあるけど、このアルゴリズムは場合によっては、次数が大きいとこの計算が急速にしんどくなるので、実装した甲斐がないなぁという感。アルゴリズム(3.2)を実装してないから、使いにくくてしょうがないし

/*
例1:
residue(y , [x+y , y^2] , [x,y], [2,1]);

例2:
Computing Multidimensional Residues
http://arxiv.org/abs/alg-geom/9404011
の末尾にある例
residue(x^2*y^3*z^2 , [x^5+y^3+z^2-1 , x^2+y^2+z-1 , x^6+y^5+z^3-1] , [x,y,z] , [3,4,7]);

*/
def residue(H , Polys , Vars , Weights){
    if(length(Polys)!=length(Vars)){
       error("mismatch number of polynomials and variables@residue");
    }
    if(length(Vars)!=length(Weights)){
       error("mismatch number of variables and weights@residue");
    }
    /* step 1 */
    T = uc();
    HPolys = newvect(length(Polys));
    Degs = newvect(length(Weights));
    for(I = 0 ; I < length(Weights) ; I++){
       Degs[I] = deg(Polys[I] , Vars[I]) - 1;
       HPolys[I] = Polys[I];
       for(J = 0 ; J < length(Vars) ; J++){
          HPolys[I] = subst(HPolys[I] , Vars[J] , Vars[J]*T^(-Weights[J]));
       }
       HPolys[I] *= T^(Weights[I]*(Degs[I]+1));
    }
    /* step 2 */
    D_min = 0;
    D_max = 0;
    for(I = 0 ; I < length(Weights) ; I++){
       D_max += Weights[I] * (Degs[I]+1);
       D_min += Weights[I] * Degs[I];
    }
    DS = [];
    for(Terms = p_terms(H,Vars,0) ; Terms!=[] ; Terms=cdr(Terms)){
       Term = car(Terms);
       D = 0;
       for(I = 0; I < length(Vars) ; I++){
          D += deg(Term , Vars[I]) * Weights[I];
       }
       DS = cons(D,DS);
    }
    D = D_min;
    for(I = 0 ; I < length(DS) ; I++){
       if(DS[I] > D_max)continue;
       if(DS[I] > D)D=DS[I];
    }
    /* step 3 */
    B = 1;
    for(I = 0 ; I < length(HPolys) ; I++)B *= 1/HPolys[I];
    Bt = newvect(D-D_min+1);
    for(C=red(B) , N=1 , I=0 ; I<=D - D_min ; I++){
       Bt[I] = subst(C , T, 0)/N;
       if(I == D - D_min)break;
       N *= (I+1);
       C = red(diff(C , T));
    }
    /* step 4 */
    Ret = 0;
    for(Terms = p_terms(H,Vars,0) ; Terms!=[] ; Terms=cdr(Terms)){
       Term = car(Terms);
       Indices = newvect(length(Vars));
       D = 0;
       Coef = H;
       for(I = 0; I < length(Vars) ; I++){
          Indices[I] = deg(Term , Vars[I]);
          D += Indices[I] * Weights[I];
          Coef = coef(Coef , Indices[I] , Vars[I]);
       }
       if (D > D_max || D < D_min)continue;
       LP = Bt[D-D_min];
       DN = dn(LP);
       V = nm(LP);
       for(I = 0 ; I < length(Vars) ; I++){
          V = coef(V , deg(DN , Vars[I])-Indices[I]-1 , Vars[I]);
          DN = coef(DN , deg(DN , Vars[I]) , Vars[I]);
          if(V==0)break;
       }
       Ret += Coef*V/DN;
    }
    return Ret;
}

[多変数のlocal residueを計算するアルゴリズム]
local residueを計算するアルゴリズムもあるっぽい。


多変数有理関数の留数計算について
http://repository.kulib.kyoto-u.ac.jp/dspace/handle/2433/62806

零次元代数的局所コホモロジー類に付随するホロノミック系の構成アルゴリズム (超局所解析の展望)
http://repository.kulib.kyoto-u.ac.jp/dspace/handle/2433/24911

多変数留数の計算代数解析とホロノミーD加群
http://repository.kulib.kyoto-u.ac.jp/dspace/handle/2433/58958


完全なアルゴリズムの説明は、2つ目にある模様。けれど、どう実装すればいいのか、あんまり検討つかないのと、差し当たって必要ないので、とりあえず保留