⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 makewfta.cpp

📁 任意精度计算的实现
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <iostream>
#include <iomanip>
#include <fstream>
#include "ap.h"


using namespace std;


// Program for creating the WFTA tables

// CEXT should be defined in the makefile
#ifndef CEXT
#define CEXT ".cpp"
#endif

const int NALGS = 41;

// W factor tables for prime WFTA components
modint w2[2], w3[3], w4[4], w5[6], w7[9], w8[8], w9[11], w16[18];
modint iw2[2], iw3[3], iw4[4], iw5[6], iw7[9], iw8[8], iw9[11], iw16[18];

modint *wt[] = {0, 0, w2, w3, w4, w5, 0, w7, w8, w9, 0, 0, 0, 0, 0, 0, w16};
modint *iwt[] = {0, 0, iw2, iw3, iw4, iw5, 0, iw7, iw8, iw9, 0, 0, 0, 0, 0, 0, iw16};

// All possible transform lengths
int n[] = {2, 3, 4, 5, 6, 8, 9, 10, 12, 16,
           18, 20, 24, 30, 36, 40, 48, 60, 72, 80,
           84, 90, 120, 144, 168, 180, 240, 252, 280, 336,
           360, 420, 504, 560, 720, 840, 1008, 1260, 1680, 2520,
           5040};

// Sequences for all possible transform lengths
int s2[] = {2}, s3[] = {3}, s4[] = {4}, s5[] = {5}, s6[] = {3, 2},
    s8[] = {8}, s9[] = {9}, s10[] = {2, 5}, s12[] = {3, 4}, s16[] = {16},
    s18[] = {2, 9}, s20[] = {4, 5}, s24[] = {3, 8}, s30[] = {3, 2, 5},
    s36[] = {4, 9}, s40[] = {8, 5}, s48[] = {3, 16}, s60[] = {3, 4, 5},
    s72[] = {8, 9}, s80[] = {16, 5}, s84[] = {3, 4, 7}, s90[] = {2, 9, 5},
    s120[] = {3, 8, 5}, s144[] = {16, 9}, s168[] = {3, 8, 7}, s180[] = {4, 9, 5},
    s240[] = {3, 16, 5}, s252[] = {4, 9, 7}, s280[] = {8, 7, 5},
    s336[] = {3, 16, 7}, s360[] = {8, 9, 5}, s420[] = {3, 4, 7, 5},
    s504[] = {8, 9, 7}, s560[] = {16, 7, 5}, s720[] = {16, 9, 5},
    s840[] = {3, 8, 7, 5}, s1008[] = {16, 9, 7}, s1260[] = {4, 9, 7, 5},
    s1680[] = {3, 16, 7, 5}, s2520[] = {8, 9, 7, 5}, s5040[] = {16, 9, 7, 5};

int *s[] = {s2, s3, s4, s5, s6, s8, s9, s10, s12, s16,
            s18, s20, s24, s30, s36, s40, s48, s60, s72, s80,
            s84, s90, s120, s144, s168, s180, s240, s252, s280, s336,
            s360, s420, s504, s560, s720, s840, s1008, s1260, s1680, s2520,
            s5040};

// Multiplication counts
int m[] = {2, 3, 4, 6, 6, 8, 11, 12, 12, 18,
           22, 24, 24, 36, 44, 48, 54, 72, 88, 108,
           108, 132, 144, 198, 216, 264, 324, 396, 432, 486,
           528, 648, 792, 972, 1188, 1296, 1782, 2376, 2916, 4752,
           10692};

// Optimized multiplication counts
int mo[] = {0, 2, 1, 5, 6, 4, 10, 12, 12, 13,
            22, 24, 24, 36, 44, 48, 54, 72, 88, 108,
            108, 132, 144, 198, 216, 264, 324, 396, 432, 486,
            528, 648, 792, 972, 1188, 1296, 1782, 2376, 2916, 4752,
            10692};

// Multiplication sequences
int ms2[] = {2}, ms3[] = {3}, ms4[] = {4}, ms5[] = {6}, ms6[] = {3, 2},
    ms8[] = {8}, ms9[] = {11}, ms10[] = {2, 6}, ms12[] = {3, 4}, ms16[] = {18},
    ms18[] = {2, 11}, ms20[] = {4, 6}, ms24[] = {3, 8}, ms30[] = {3, 2, 6},
    ms36[] = {4, 11}, ms40[] = {8, 6}, ms48[] = {3, 18}, ms60[] = {3, 4, 6},
    ms72[] = {8, 11}, ms80[] = {18, 6}, ms84[] = {3, 4, 9}, ms90[] = {2, 11, 6},
    ms120[] = {3, 8, 6}, ms144[] = {18, 11}, ms168[] = {3, 8, 9}, ms180[] = {4, 11, 6},
    ms240[] = {3, 18, 6}, ms252[] = {4, 11, 9}, ms280[] = {8, 9, 6},
    ms336[] = {3, 18, 9}, ms360[] = {8, 11, 6}, ms420[] = {3, 4, 9, 6},
    ms504[] = {8, 11, 9}, ms560[] = {18, 9, 6}, ms720[] = {18, 11, 6},
    ms840[] = {3, 8, 9, 6}, ms1008[] = {18, 11, 9}, ms1260[] = {4, 11, 9, 6},
    ms1680[] = {3, 18, 9, 6}, ms2520[] = {8, 11, 9, 6}, ms5040[] = {18, 11, 9, 6};

int *ms[] = {ms2, ms3, ms4, ms5, ms6, ms8, ms9, ms10, ms12, ms16,
             ms18, ms20, ms24, ms30, ms36, ms40, ms48, ms60, ms72, ms80,
             ms84, ms90, ms120, ms144, ms168, ms180, ms240, ms252, ms280, ms336,
             ms360, ms420, ms504, ms560, ms720, ms840, ms1008, ms1260, ms1680, ms2520,
             ms5040};

// Permutation tables
int p6[6], p10[12], p12[12], p18[18], p20[20],
    p24[24], p30[30], p36[36], p40[40], p48[48],
    p60[60], p72[72], p80[80], p84[84], p90[90],
    p120[120], p144[144], p168[168], p180[180], p240[240],
    p252[252], p280[280], p336[336], p360[360], p420[420],
    p504[504], p560[560], p720[720], p840[840], p1008[1008],
    p1260[1260], p1680[1680], p2520[2520], p5040[5040];

int ip6[6], ip10[12], ip12[12], ip18[18], ip20[20],
    ip24[24], ip30[30], ip36[36], ip40[40], ip48[48],
    ip60[60], ip72[72], ip80[80], ip84[84], ip90[90],
    ip120[120], ip144[144], ip168[168], ip180[180], ip240[240],
    ip252[252], ip280[280], ip336[336], ip360[360], ip420[420],
    ip504[504], ip560[560], ip720[720], ip840[840], ip1008[1008],
    ip1260[1260], ip1680[1680], ip2520[2520], ip5040[5040];

int *p[] = {0, 0, 0, 0, p6, 0, 0, p10, p12, 0,
            p18, p20, p24, p30, p36, p40, p48, p60, p72, p80,
            p84, p90, p120, p144, p168, p180, p240, p252, p280, p336,
            p360, p420, p504, p560, p720, p840, p1008, p1260, p1680, p2520,
            p5040};

int *ip[] = {0, 0, 0, 0, ip6, 0, 0, ip10, ip12, 0,
             ip18, ip20, ip24, ip30, ip36, ip40, ip48, ip60, ip72, ip80,
             ip84, ip90, ip120, ip144, ip168, ip180, ip240, ip252, ip280, ip336,
             ip360, ip420, ip504, ip560, ip720, ip840, ip1008, ip1260, ip1680, ip2520,
             ip5040};

// W tables for composite WFTA lengths
modint w6[6], w10[12], w12[12], w18[22], w20[24],
       w24[24], w30[36], w36[44], w40[48], w48[54],
       w60[72], w72[88], w80[108], w84[108], w90[132],
       w120[144], w144[198], w168[216], w180[264], w240[324],
       w252[396], w280[432], w336[486], w360[528], w420[648],
       w504[792], w560[972], w720[1188], w840[1296], w1008[1782],
       w1260[2376], w1680[2916], w2520[4752], w5040[10692];

modint iw6[6], iw10[12], iw12[12], iw18[22], iw20[24],
       iw24[24], iw30[36], iw36[44], iw40[48], iw48[54],
       iw60[72], iw72[88], iw80[108], iw84[108], iw90[132],
       iw120[144], iw144[198], iw168[216], iw180[264], iw240[324],
       iw252[396], iw280[432], iw336[486], iw360[528], iw420[648],
       iw504[792], iw560[972], iw720[1188], iw840[1296], iw1008[1782],
       iw1260[2376], iw1680[2916], iw2520[4752], iw5040[10692];

modint *w[] = {w2, w3, w4, w5, w6, w8, w9, w10, w12, w16,
               w18, w20, w24, w30, w36, w40, w48, w60, w72, w80,
               w84, w90, w120, w144, w168, w180, w240, w252, w280, w336,
               w360, w420, w504, w560, w720, w840, w1008, w1260, w1680, w2520,
               w5040};

modint *iw[] = {iw2, iw3, iw4, iw5, iw6, iw8, iw9, iw10, iw12, iw16,
                iw18, iw20, iw24, iw30, iw36, iw40, iw48, iw60, iw72, iw80,
                iw84, iw90, iw120, iw144, iw168, iw180, iw240, iw252, iw280, iw336,
                iw360, iw420, iw504, iw560, iw720, iw840, iw1008, iw1260, iw1680, iw2520,
                iw5040};

void createpermutetable (int p[], int ip[], int s[], int n)
{
    int k, t, u, v, m[4] = {1, 1, 1, 1}, r[4], j[4];

    for (t = n, k = 0; t > 1; t /= s[k], k++);

    for (t = 0; t < k; t++)
        for (u = 0; u < k; u++)
            if (u != t) m[t] *= s[u];

    for (t = 0; t < k; t++)
        for (u = 1; u < s[t]; u++)
            if (u * m[t] % s[t] == 1)
            {
                r[t] = u;
                break;
            }

    for (t = 0; t < n; t++)
    {
        v = t;
        for (u = k - 1; u >= 0; u--)
        {
            j[u] = v % s[u];
            v /= s[u];
        }

        v = 0;
        for (u = 0; u < k; u++)
            v += r[u] * j[u] * m[u];

        p[t] = v % n;

        v = 0;
        for (u = 0; u < k; u++)
            v += j[u] * m[u];

        ip[t] = v % n;
    }
}

void createpermutetables (void)
{
    int t;

    for (t = 0; t < NALGS; t++)
        if (p[t]) createpermutetable (p[t], ip[t], s[t], n[t]);
}

modint rcos (modint w)
{
    return (w * w + modint (1)) / (w + w);
}

modint isin (modint w)
{
    return (w * w - modint (1)) / (w + w);
}

modint root (modint pr, int n)
{
    // return pow (pr, modint::modulus - 1 - (modint::modulus - 1) / n);
    return pow (pr, (modint::modulus - 1) / n);
}

void createw2table (modint pr, modint w2[], modint iw2[])
{
    w2[0] = iw2[0] = w2[1] = iw2[1] = 1;
}

void createw3table (modint pr, modint w3[], modint iw3[])
{
    modint w, c, s;

    w = root (pr, 3);

    c = rcos (w);
    s = isin (w);

    w3[0] = iw3[0] = 1;
    w3[1] = iw3[1] = c - modint (1);
    w3[2] = -(iw3[2] = s);
}

void createw4table (modint pr, modint w4[], modint iw4[])
{
    modint i;

    i = root (pr, 4);

    w4[0] = iw4[0] = w4[1] = iw4[1] = w4[2] = iw4[2] = 1;
    w4[3] = -(iw4[3] = i);
}

void createw5table (modint pr, modint w5[], modint iw5[])
{
    modint w, c1, c2, s1, s2;

    w = root (pr, 5);

    c1 = rcos (w);
    s1 = isin (w);

    w *= w;

    c2 = rcos (w);
    s2 = isin (w);

    w5[0] = iw5[0] = 1;
    w5[1] = iw5[1] = (c1 + c2) / modint (2) - modint (1);
    w5[2] = iw5[2] = (c1 - c2) / modint (2);
    w5[3] = -(iw5[3] = s1);
    w5[4] = -(iw5[4] = s2 + s1);
    w5[5] = -(iw5[5] = s2 - s1);
}

void createw7table (modint pr, modint w7[], modint iw7[])
{
    modint w, c1, c2, c3, s1, s2, s3;

    w = root (pr, 7);

    c1 = rcos (w);
    s1 = isin (w);

    c2 = rcos (w * w);
    s2 = isin (w * w);

    c3 = rcos (w * w * w);
    s3 = isin (w * w * w);

    w7[0] = iw7[0] = 1;
    w7[1] = iw7[1] = (c1 + c2 + c3) / modint (3) - modint (1);
    w7[2] = iw7[2] = (modint (2) * c1 - c2 - c3) / modint (3);
    w7[3] = iw7[3] = (c1 - modint (2) * c2 + c3) / modint (3);
    w7[4] = iw7[4] = (c1 + c2 - modint (2) * c3) / modint (3);
    w7[5] = -(iw7[5] = (s1 + s2 - s3) / modint (3));
    w7[6] = -(iw7[6] = (modint (2) * s1 - s2 + s3) / modint (3));
    w7[7] = -(iw7[7] = (s1 - modint (2) * s2 - s3) / modint (3));
    w7[8] = -(iw7[8] = (s1 + s2 + modint (2) * s3) / modint (3));
}

void createw8table (modint pr, modint w8[], modint iw8[])
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -