Quantcast
Channel: 円周率近似値の日に生まれて理系じゃないわけないだろ! - knifeのblog
Viewing all articles
Browse latest Browse all 5376

C言語でチェビシェフの多項式を導く

$
0
0

昨日のExcelの検証用に作ったプログラムについて、書いていきます。

言語はC言語です。

まぁ、前々回、前回とチェビシェフの多項式がなんたるかは解っていらっしゃるでしょうから、いきなりですがソースです。
 

#include <stdio.h>
#include <stdlib.h>

int main()
{
    long long int k[3][101];
    int i, j;

    k[0][0] = k[1][1] = 1;
    k[0][1] = k[1][0] = 0;
    for (j=2; j<101; j++) {
        k[0][j] = 0;
        k[1][j] = 0;
    }
    printf("T<sub>0</sub>(x)=+1<br>\nT<sub>1</sub>(x)=+x<br>\n");
    i = 2;
    while ( i < 101 ) {
        k[i%3][0] = -k[(i+1)%3][0];
        for (j=1; j<101; j++) {
            if ( k[(i+2)%3][j-1] > 0 && 2*k[(i+2)%3][j-1] < 0 ) break;
            if ( k[(i+2)%3][j-1] < 0 && 2*k[(i+2)%3][j-1] > 0 ) break;
            if ( 2*k[(i+2)%3][j-1] > 0 && 2*k[(i+2)%3][j-1]-k[(i+1)%3][j] < 0 ) break;
            if ( 2*k[(i+2)%3][j-1] < 0 && 2*k[(i+2)%3][j-1]-k[(i+1)%3][j] > 0 ) break;
            k[i%3][j] = 2*k[(i+2)%3][j-1]-k[(i+1)%3][j];
        }
        if ( j < 101 ) break;
    /*
        for (j=0; j<99; j++) {
            if ( k[i%3][j] > 0 && k[i%3][j+2] > 0 ) break;
            if ( k[i%3][j] < 0 && k[i%3][j+2] < 0 ) break;
        }
        if ( j < 99 ) break;
    */
        printf("T<sub>%d</sub>(x)=",i);
        for (j=100; j>1; j--) {
            if ( k[i%3][j] > 0 ) {
                printf("+%lld",k[i%3][j]);
                printf("x<sup>");
                printf("%d",j);
                printf("</sup>");
            } else if ( k[i%3][j] < 0 ) {
                printf("%lld",k[i%3][j]);
                printf("x<sup>");
                printf("%d",j);
                printf("</sup>");
            }
        }
        if ( k[i%3][j] > 1 ) {
            printf("+%lld",k[i%3][j]);
            printf("x");
        } else if ( k[i%3][j] == 1 ) {
            printf("+x");
        } else if ( k[i%3][j] < 0 ) {
            printf("%lld",k[i%3][j]);
            printf("x");
        }
        j--;
        if ( k[i%3][j] > 0 ) {
            printf("+%lld",k[i%3][j]);
        } else if ( k[i%3][j] < 0 ) {
            printf("%lld",k[i%3][j]);
        }
        printf("<br>\n");
        i++;
    }

    return EXIT_SUCCESS;
}

 

ざっと解説すると、
long long int型、つまり64ビット整数型ですね。

k[3][101]は係数の格納用です。
[101]はx0からx100の係数までを格納するため101個。
それに比べて[3]って少なすぎじゃない?と思われるかもしれません。
本来なら指数と同じようにT0(x)のT100(x)までの101個の配列を用意しなければならないでしょう。
ただね、そんなにあっても無駄なんですよ。
データ参照として2個前までで良いので、3個で十分なんです。
使わなくなったデータのところに新しいデータを上書きする方法です。
つまりリングバッファ的な作り込みです。
もっと言えば、[101]も[51]で十分なんですが、プログラムが汚くなりそうなので、やめておきました。

64ビット型ですから、1バイト=8ビットなので、4バイトです。
101×101も作ったら、40804バイト、約49KBメモリーを使うんです。
3×101ならば、1212バイト、約1.18KBメモリーで済みます。
まぁ、こういうテクニックもいずれは廃れていくのだろうか。

今回の肝はオーバーフローの検出だろう。

コメントアウトしてあるのが、最初に考えた検出方法で、
 

        for (j=0; j<99; j++) {
            if ( k[i%3][j] > 0 && k[i%3][j+2] > 0 ) break;
            if ( k[i%3][j] < 0 && k[i%3][j+2] < 0 ) break;
        }
        if ( j < 99 ) break;


これは、チェビシェフの多項式の性質で、降べきの順、昇べきの順、どちらであったとしても、符号が交互に入れ替わるというということに着目して、データ上、2つ後ろの項と符号が同じなら、breakしてforループから抜ける。
forループが最後まで行われなかったら、大外のwhileループからも抜ける。

現状、採用したのがこちらです。
 

        for (j=1; j<101; j++) {
            if ( k[(i+2)%3][j-1] > 0 && 2*k[(i+2)%3][j-1] < 0 ) break;
            if ( k[(i+2)%3][j-1] < 0 && 2*k[(i+2)%3][j-1] > 0 ) break;
            if ( 2*k[(i+2)%3][j-1] > 0 && 2*k[(i+2)%3][j-1]-k[(i+1)%3][j] < 0 ) break;
            if ( 2*k[(i+2)%3][j-1] < 0 && 2*k[(i+2)%3][j-1]-k[(i+1)%3][j] > 0 ) break;
            k[i%3][j] = 2*k[(i+2)%3][j-1]-k[(i+1)%3][j];
        }
        if ( j < 101 ) break;


2倍するタイミングで符号が変わったら、breakしてforループから抜ける。
減算するタイミングで符号が変わったら、breakしてforループから抜ける。
forループが最後まで行われなかったら、大外のwhileループからも抜ける。

なぜ、こちらを採用したかと言えば、これが一般的なオーバーフロー検出だと私は考えているからです。
まぁ、どちらにしても同じところまでしか出力しなかったので、採用しなかったオーバーフロー検出も、今回に限って言えばそこまで悪くはなかったとも言えます。
また、Excelの回のときに使った方法、係数を全部足すと1になるという方法も良いかとは思います。

そもそも、このプログラムはExcelのデータの正しさを証明するために作ったいい加減なものですので、まさかブログに載せるとは考えてもいませんでした。

出力をtxtファイルにリダイレクトして、それをブログへ貼りました。
どうぞごらんあれ!
 

T0(x)=+1
T1(x)=+x
T2(x)=+2x2-1
T3(x)=+4x3-3x
T4(x)=+8x4-8x2+1
T5(x)=+16x5-20x3+5x
T6(x)=+32x6-48x4+18x2-1
T7(x)=+64x7-112x5+56x3-7x
T8(x)=+128x8-256x6+160x4-32x2+1
T9(x)=+256x9-576x7+432x5-120x3+9x
T10(x)=+512x10-1280x8+1120x6-400x4+50x2-1
T11(x)=+1024x11-2816x9+2816x7-1232x5+220x3-11x
T12(x)=+2048x12-6144x10+6912x8-3584x6+840x4-72x2+1
T13(x)=+4096x13-13312x11+16640x9-9984x7+2912x5-364x3+13x
T14(x)=+8192x14-28672x12+39424x10-26880x8+9408x6-1568x4+98x2-1
T15(x)=+16384x15-61440x13+92160x11-70400x9+28800x7-6048x5+560x3-15x
T16(x)=+32768x16-131072x14+212992x12-180224x10+84480x8-21504x6+2688x4-128x2+1
T17(x)=+65536x17-278528x15+487424x13-452608x11+239360x9-71808x7+11424x5-816x3+17x
T18(x)=+131072x18-589824x16+1105920x14-1118208x12+658944x10-228096x8+44352x6-4320x4+162x2-1
T19(x)=+262144x19-1245184x17+2490368x15-2723840x13+1770496x11-695552x9+160512x7-20064x5+1140x3-19x
T20(x)=+524288x20-2621440x18+5570560x16-6553600x14+4659200x12-2050048x10+549120x8-84480x6+6600x4-200x2+1
T21(x)=+1048576x21-5505024x19+12386304x17-15597568x15+12042240x13-5870592x11+1793792x9-329472x7+33264x5-1540x3+21x
T22(x)=+2097152x22-11534336x20+27394048x18-36765696x16+30638080x14-16400384x12+5637632x10-1208064x8+151008x6-9680x4+242x2-1
T23(x)=+4194304x23-24117248x21+60293120x19-85917696x17+76873728x15-44843008x13+17145856x11-4209920x9+631488x7-52624x5+2024x3-23x
T24(x)=+8388608x24-50331648x22+132120576x20-199229440x18+190513152x16-120324096x14+50692096x12-14057472x10+2471040x8-256256x6+13728x4-288x2+1
T25(x)=+16777216x25-104857600x23+288358400x21-458752000x19+466944000x17-317521920x15+146227200x13-45260800x11+9152000x9-1144000x7+80080x5-2600x3+25x
T26(x)=+33554432x26-218103808x24+627048448x22-1049624576x20+1133117440x18-825556992x16+412778496x14-141213696x12+32361472x10-4759040x8+416416x6-18928x4+338x2-1
T27(x)=+67108864x27-452984832x25+1358954496x23-2387607552x21+2724986880x19-2118057984x17+1143078912x15-428654592x13+109983744x11-18670080x9+1976832x7-117936x5+3276x3-27x
T28(x)=+134217728x28-939524096x26+2936012800x24-5402263552x22+6499598336x20-5369233408x18+3111714816x16-1270087680x14+361181184x12-69701632x10+8712704x8-652288x6+25480x4-392x2+1
T29(x)=+268435456x29-1946157056x27+6325010432x25-12163481600x23+15386804224x21-13463453696x19+8341487616x17-3683254272x15+1151016960x13-249387008x11+36095488x9-3281408x7+168896x5-4060x3+29x
T30(x)=+536870912x30-4026531840x28+13589544960x26-27262976000x24+36175872000x22-33426505728x20+22052208640x18-10478223360x16+3572121600x14-859955200x12+141892608x10-15275520x8+990080x6-33600x4+450x2-1
T31(x)=+1073741824x31-8321499136x29+29125246976x27-60850962432x25+84515225600x23-82239815680x21+57567870976x19-29297934336x17+10827497472x15-2870927360x13+533172224x11-66646528x9+5261568x7-236096x5+4960x3-31x
T32(x)=+2147483648x32-17179869184x30+62277025792x28-135291469824x26+196293427200x24-200655503360x22+148562247680x20-80648077312x18+32133218304x16-9313976320x14+1926299648x12-275185664x10+25798656x8-1462272x6+43520x4-512x2+1
T33(x)=+4294967296x33-35433480192x31+132875550720x29-299708186624x27+453437816832x25-485826232320x23+379364311040x21-218864025600x19+93564370944x17-29455450112x15+6723526656x13-1083543552x11+118243840x9-8186112x7+323136x5-5984x3+33x
T34(x)=+8589934592x34-73014444032x32+282930970624x30-661693399040x28+1042167103488x26-1167945891840x24+959384125440x22-586290298880x20+267776819200x18-91044118528x16+22761029632x14-4093386752x12+511673344x10-42170880x8+2108544x6-55488x4+578x2-1
T35(x)=+17179869184x35-150323855360x33+601295421440x31-1456262348800x29+2384042393600x27-2789329600512x25+2404594483200x23-1551944908800x21+754417664000x19-275652608000x17+74977509376x15-14910300160x13+2106890240x11-202585600x9+12403200x7-434112x5+7140x3-35x
T36(x)=+34359738368x36-309237645312x34+1275605286912x32-3195455668224x30+5429778186240x28-6620826304512x26+5977134858240x24-4063273943040x22+2095125626880x20-819082035200x18+240999137280x16-52581629952x14+8307167232x12-916844544x10+66977280x8-2976768x6+69768x4-648x2+1
T37(x)=+68719476736x37-635655159808x35+2701534429184x33-6992206757888x31+12315818721280x29-15625695002624x27+14743599316992x25-10531142369280x23+5742196162560x21-2392581734400x19+757650882560x17-180140769280x15+31524634624x13-3940579328x11+336540160x9-18356736x7+573648x5-8436x3+37x
T38(x)=+137438953472x38-1305670057984x36+5712306503680x34-15260018802688x32+27827093110784x30-36681168191488x28+36108024938496x26-27039419596800x24+15547666268160x22-6880289095680x20+2334383800320x18-601280675840x16+115630899200x14-16188325888x12+1589924864x10-103690752x8+4124064x6-86640x4+722x2-1
T39(x)=+274877906944x39-2680059592704x37+12060268167168x35-33221572034560x33+62646392979456x31-85678155104256x29+87841744879616x27-68822438510592x25+41626474905600x23-19502774353920x21+7061349335040x19-1960212234240x17+411402567680x15-63901286400x13+7120429056x11-543921664x9+26604864x7-746928x5+9880x3-39x
T40(x)=+549755813888x40-5497558138880x38+25426206392320x36-72155450572800x34+140552804761600x32-199183403319296x30+212364657950720x28-173752901959680x26+110292369408000x24-54553214976000x22+21002987765760x20-6254808268800x18+1424085811200x16-243433472000x14+30429184000x12-2677768192x10+156900480x8-5617920x6+106400x4-800x2+1
T41(x)=+1099511627776x41-11269994184704x39+53532472377344x37-156371169312768x35+314327181557760x33-461013199618048x31+510407471005696x29-435347548798976x27+289407177326592x25-150732904857600x23+61508749885440x21-19570965872640x19+4808383856640x17-898269511680x15+124759654400x13-12475965440x11+857722624x9-37840704x7+959728x5-11480x3+41x
T42(x)=+2199023255552x42-23089744183296x40+112562502893568x38-338168545017856x36+700809813688320x34-1062579203997696x32+1219998345330688x30-1083059755548672x28+752567256612864x26-411758179123200x24+177570714746880x22-60144919511040x20+15871575982080x18-3220624834560x16+492952780800x14-55381114880x12+4393213440x10-232581888x8+7537376x6-129360x4+882x2-1
T43(x)=+4398046511104x43-47278999994368x41+236394999971840x39-729869562413056x37+1557990796689408x35-2439485589553152x33+2901009890279424x31-2676526982103040x29+1940482062024704x27-1112923535572992x25+505874334351360x23-181798588907520x21+51314117836800x19-11249633525760x17+1884175073280x15-235521884160x13+21262392320x11-1322886400x9+52915456x7-1218448x5+13244x3-43x
T44(x)=+8796093022208x44-96757023244288x42+495879744126976x40-1572301627719680x38+3454150138396672x36-5579780992794624x34+6864598984556544x32-6573052309536768x30+4964023879598080x28-2978414327758848x26+1423506847825920x24-541167892561920x22+162773155184640x20-38370843033600x18+6988974981120x16-963996549120x14+97905899520x12-7038986240x10+338412800x8-9974272x6+155848x4-968x2+1
T45(x)=+17592186044416x45-197912092999680x43+1039038488248320x41-3380998255411200x39+7638169839206400x37-12717552782278656x35+16168683558666240x33-16047114509352960x31+12604574741299200x29-7897310717542400x27+3959937231224832x25-1588210119475200x23+507344899276800x21-128055803904000x19+25227583488000x17-3812168171520x15+431333683200x13-35340364800x11+1999712000x9-72864000x7+1530144x5-15180x3+45x
T46(x)=+35184372088832x46-404620279021568x44+2174833999740928x42-7257876254949376x40+16848641306132480x38-28889255702953984x36+37917148110127104x34-38958828003262464x32+31782201792135168x30-20758645314682880x28+10898288790208512x26-4599927086776320x24+1555857691115520x22-418884762992640x20+88826010009600x18-14613311324160x16+1826663915520x14-168586629120x12+11038410240x10-484140800x8+13034560x6-186208x4+1058x2-1
T47(x)=+70368744177664x47-826832744087552x45+4547580092481536x43-15554790998147072x41+37078280867676160x39-65416681245114368x37+88551849002532864x35-94086339565191168x33+79611518093623296x31-54121865370664960x29+29693888297959424x27-13159791404777472x25+4699925501706240x23-1345114425262080x21+305707823923200x19-54454206136320x17+7465496002560x15-768506941440x13+57417185280x11-2967993600x9+98933120x7-1902560x5+17296x3-47x
T48(x)=+140737488355328x48-1688849860263936x46+9499780463984640x44-33284415996035072x42+81414437990301696x40-147682003796361216x38+205992953708019712x36-226089827240509440x34+198181864190509056x32-140025932533465088x30+80146421910601728x28-37217871599763456x26+13999778090188800x24-4246086541639680x22+1030300410839040x20-197734422282240x18+29544303329280x16-3363677798400x14+283420999680x12-16974397440x10+682007040x8-16839680x6+220800x4-1152x2+1
T49(x)=+281474976710656x49-3448068464705536x47+19826393672056832x45-71116412084551680x43+178383666978750464x41-332442288460398592x39+477402588661153792x37-540731503483551744x35+490450067946209280x33-359663383160553472x31+214414709191868416x29-104129631497486336x27+41159347585155072x25-13192098584985600x23+3405715246940160x21-701176668487680x19+113542812794880x17-14192851599360x15+1335348940800x13-91365980160x11+4332007680x9-132612480x7+2344160x5-19600x3+49x
T50(x)=+562949953421312x50-7036874417766400x48+41341637204377600x46-151732604633088000x44+390051749953536000x42-746299014911098880x40+1102487181118668800x38-1287455960675123200x36+1206989963132928000x34-917508630511616000x32+568855350917201920x30-288405684905574400x28+119536566770073600x26-40383975260160000x24+11057517035520000x22-2432653747814400x20+424820047872000x18-57930006528000x16+6034375680000x14-466152960000x12+25638412800x10-947232000x8+21528000x6-260000x4+1250x2-1
T51(x)=+1125899906842624x51-14355223812243456x49+86131342873460736x47-323291602938232832x45+851219911991623680x43-1670981696800948224x41+2537416650697736192x39-3052314510011400192x37+2954711429749407744x35-2325467328969441280x33+1497374084994957312x31-791226079003017216x29+343202765037633536x27-121927298105475072x25+35307132656025600x23-8271022742568960x21+1550816764231680x19-229402825850880x17+26261602959360x15-2267654860800x13+142642805760x11-6226471680x9+175668480x7-2864160x5+22100x3-51x
T52(x)=+2251799813685248x52-29273397577908224x50+179299560164687872x48-687924843080843264x46+1854172428616335360x44-3732015143555432448x42+5821132316306571264x40-7207116201141469184x38+7196878820173938688x36-5857924621071810560x34+3912256800501530624x32-2151307508923236352x30+974811214980841472x28-363391162981023744x26+110998240572211200x24-27599562520657920x22+5534287276277760x20-883625699573760x18+110453212446720x16-10569685401600x14+751438571520x12-38091356160x10+1298568960x8-27256320x6+304200x4-1352x2+1

 

64ビット整数で52次が限界のようですね。

128ビットCPUとか、
128ビットOSとか、
128ビットプログラミング言語とか、
そういう時代がそろそろ来てもよさそうな気がしますが、
そこまで求めないのだろうか。

本気でやる人は、CPUが128ビットになる前に、プログラミングで多倍長演算させてでも、桁数を増やしてくるでしょうね。
今回はやりませんよ。


ではでは


Viewing all articles
Browse latest Browse all 5376

Trending Articles