MUSASHI C source: xtbucket.c
0001:
0002: /*============================================================================*/
0003: /* 変更履歴 */
0004: /*----------------------------------------------------------------------------*/
0005: /* 1.0 : 新しいAPIに対応 2003/06/20 */
0006: /*============================================================================*/
0007: #include <musashi.h>
0008: #include <stdlib.h>
0009: #include <string.h>
0010: #include <float.h>
0011:
0012: #include <xtbucketHelp.h>
0013: struct mssComHelp comHelp={
0014: "xtbucket", /* コマンド名 */
0015: "1.0", /* バージョン */
0016: HELPT, /* コマンドタイトル */
0017: HELPS, /* 要約 */
0018: HELPE, /* 利用例 */
0019: HELPR, /* 参照コマンド */
0020: HELPA, /* 作者情報 */
0021: HELPB, /* バグレポート情報 */
0022: HELPH /* ホームページ */
0023: };
0024:
0025: extern struct mssGlobalVariables mssGV;
0026:
0027: #define MALLOC_CNT 1000
0028:
0029: struct ctbl { /*count table*/
0030: double Val;
0031: unsigned long Cnt;
0032: };
0033:
0034: struct kTbl { /*k-cluster table*/
0035: double minVar;
0036: unsigned long prvNo;
0037: unsigned long from;
0038: unsigned long to;
0039: };
0040:
0041: struct rTbl { /*range table*/
0042: double from;
0043: double to;
0044: };
0045:
0046: static struct ctbl *cTable; /*値とその件数の入った配列*/
0047: static long cTableCnt; /*各cTable配列に登録されている件数*/
0048: static long cTableMaxCnt; /*各cTable配列に登録可能最大件数(malloc)*/
0049:
0050: static struct kTbl *kTable;
0051: static struct rTbl *rTable;
0052: static unsigned long *sTable;
0053: static struct rTbl **rTables;
0054:
0055: int cutCnt; /*実際の分割数*/
0056:
0057: void insertValue(
0058: double value, /*挿入する値*/
0059: int start /*挿入するスタート位置*/
0060: ){
0061: int i;
0062:
0063: /*メモリオーバー時のリアロケーション(MALLOC_CNT行単位で増える) */
0064: if( cTableCnt >= cTableMaxCnt) {
0065: cTableMaxCnt+=MALLOC_CNT;
0066: cTable = (struct ctbl *)mssRealloc(cTable,
0067: cTableMaxCnt * sizeof(struct ctbl),"xtbucket");
0068: }
0069:
0070: for(i=cTableCnt-1; i>=start; i--){
0071: (cTable+i+1)->Val = (cTable+i)->Val;
0072: (cTable+i+1)->Cnt = (cTable+i)->Cnt;
0073: }
0074: (cTable+start)->Val = value;
0075: (cTable+start)->Cnt = 1;
0076: cTableCnt++;
0077: }
0078:
0079: void setCntTable(char *str){
0080: /*バイナリサーチで探索するスタート位置とエンド位置とその中間値*/
0081: double value; /*テーブルにセットする値*/
0082: int start;
0083: int end;
0084: int try=0;
0085:
0086: if(MssIsNull(str))return;
0087:
0088: value=atof(str);
0089: /*探索中に同じ値がテーブルに見つかればカウントアップ*/
0090: /*見つからなければstartの位置にその値を挿入する*/
0091: start=0;
0092: end=cTableCnt-1;
0093: while(start<=end){
0094: try=(start+end)/2;
0095: if((cTable+try)->Val > value) {
0096: end=try-1;
0097: } else if((cTable+try)->Val < value) {
0098: start=try+1;
0099: } else {
0100: (cTable+try)->Cnt++;
0101: return;
0102: }
0103: }
0104: /*探索で見つからなければその値をテーブルに新規登録*/
0105: insertValue(value, start);
0106: return;
0107: }
0108:
0109:
0110: /*----------------------------------------------------------------------------*/
0111: /*データのメモリへのセット
0112: cTable[i]にセットされる iはf=で指定した項目番号を0から順番に割り振った番号
0113: ex)f=2,5の場合 cTable[0]が項目2,cTable[1]が項目5
0114: cTable[i]にmallocで確保された領域の先頭アドレスがセットされる。
0115: 領域は次の構造体のデータ構造を持つ
0116: double Val; 値
0117: unsigned long Cnt; その値の出現件数
0118: */
0119: /*----------------------------------------------------------------------------*/
0120: struct ctbl *setcTable(struct mssFldRecKey *frk,int fldNo){
0121: /* int i;*/
0122:
0123: cTableMaxCnt=MALLOC_CNT;
0124: cTable =NULL;
0125: cTable =(struct ctbl *)mssCalloc(cTableMaxCnt*sizeof(struct ctbl),"xtbucket");
0126:
0127: mssSeekTopFRK(frk);
0128: while( EOF != mssReadFldRecFRK(frk) ){
0129: /*項目の値をセットする*/
0130: setCntTable(*(frk->pnt+fldNo));
0131: }
0132:
0133: /* デバッグリスト*/
0134: /*
0135: for(i=0; i<cTableCnt; i++){
0136: printf("field[%d] %g - %ld\n",i,(cTable+i)->Val,(cTable+i)->Cnt);
0137: }
0138: */
0139: return(cTable);
0140: }
0141:
0142: /*cTableにおいて、startからendまでの件数二乗和を求める*/
0143: /*分散最小化は件数の二乗和最小化に等しいので*/
0144: double calVariance( int start, int end){
0145: double result=0;
0146: int i;
0147: for(i=start; i<=end; i++){
0148: result+=(cTable+i)->Cnt;
0149: }
0150: return(result*result);
0151: }
0152:
0153: /*----------------------------------------------------------------------------*/
0154: /* 最適カットポイントを求める */
0155: /*----------------------------------------------------------------------------*/
0156: /*
0157: Algorithm by N.Katoh
0158: kTableとは、分散最小化を求めるためのワークテーブルで以下のような構造をとる
0159: kTableからrTableが作られる。
0160:
0161: 分割数 値1 値2 値3 ... 値k
0162: 1 a(1,1) a(1,2) a(1,3) ... a(1,k)
0163: 2 a(2,1) a(2,2) a(2,3) ... a(2,k)
0164: 3 a(3,1) a(3,2) a(3,3) ... a(3,k)
0165: . . . . ... .
0166: . . . . ... .
0167: j a(j,1) a(j,2) a(j,3) ... a(j,k)
0168:
0169: a(j,k)には次の構造体を持つ
0170: double minVar;
0171: unsigned long prvNo;
0172: unsigned long from;
0173: unsigned long to;
0174: minVarは、k個の値についてj分割したときの最小分散値
0175: ただし、分散値は用いる必要はなく、単に件数の2乗値で代替することができる
0176: prvNoは、j分割の場合に、最小分散値を持つようなj-1分割時のk。
0177: from,toは、j分割の場合に、最小分散値を持つようなj番目の分割範囲。
0178:
0179: 分割数1の行は、実際にはcTableの件数の2乗和が入っている
0180: */
0181: /*----------------------------------------------------------------------------*/
0182: void calOptCutPoint(int cutNum){
0183:
0184: unsigned long maxCnt;
0185: double minMinVar=0;
0186: unsigned long minPrvNo=0;
0187: unsigned long minFrom=0;
0188: unsigned long minTo=0;
0189: double tmpVar;
0190: struct kTbl *tmpKtbl;
0191: int j,k,l;
0192:
0193: maxCnt=cTableCnt; /* 値の種類数 */
0194: /*kTableメモリアロケーション*/
0195: kTable = (struct kTbl *)mssCalloc(
0196: maxCnt*cutNum*sizeof(struct kTbl),"calOptCutP");
0197: /*sTableメモリアロケーション*/
0198: sTable = (unsigned long *)mssCalloc(
0199: maxCnt*sizeof(unsigned long),"calOptCutP");
0200: /*rTableメモリアロケーション*/
0201: rTable = (struct rTbl *)mssCalloc(
0202: cutNum*sizeof(struct rTbl),"calOptCutP");
0203:
0204: /*累積値を持っておく*/
0205: *sTable = cTable->Cnt;
0206: for(j=1; j<cTableCnt; j++){
0207: *(sTable+j) = *(sTable+j-1) + (cTable+j)->Cnt;
0208: }
0209:
0210: /*k=1の場合の計算*/
0211: for(j=0; j<cTableCnt; j++){
0212: (kTable+j)->minVar = calVariance(0,j);
0213: (kTable+j)->prvNo = 0;
0214: (kTable+j)->from = 0;
0215: (kTable+j)->to = j;
0216: }
0217:
0218: /*値の種類数よりもカット数(k=の値)が大きければcutCntを調整*/
0219: cutCnt=cutNum;
0220: if(cutNum>cTableCnt)cutCnt=cTableCnt;
0221:
0222: /*k=2以上の場合の計算*/
0223: for(j=1; j<cutCnt; j++){ /*j=1で始まるのはk分割の1は配列の0に対応*/
0224: for(k=j; k<cTableCnt; k++){
0225: minMinVar=DBL_MAX;
0226: for(l=j-1; l<k; l++){
0227: tmpVar = (kTable+cTableCnt*(j-1)+l)->minVar +
0228: (double)(sTable[k]-sTable[l])*(double)(sTable[k]-sTable[l]);
0229: /*ここの不等式を>にすれば、同じ件数の場合に後を多くする*/
0230: /*ここの不等式を>=にすれば、同じ件数の場合に前を多くする*/
0231: if( minMinVar > tmpVar ){
0232: minMinVar =tmpVar;
0233: minPrvNo =l;
0234: minFrom =l+1;
0235: minTo =k;
0236: }
0237: } /*for l*/
0238: (kTable+cTableCnt*j+k)->minVar = minMinVar;
0239: (kTable+cTableCnt*j+k)->prvNo = minPrvNo;
0240: (kTable+cTableCnt*j+k)->from = minFrom;
0241: (kTable+cTableCnt*j+k)->to = minTo;
0242: }/*for k*/
0243: } /*for j*/
0244:
0245: tmpKtbl=kTable+cutCnt*cTableCnt-1;
0246: for(j=cutCnt-1; j>=0; j--){
0247: //(rTable+cutNum+j)->from=(cTable+(tmpKtbl->from))->Val;
0248: //(rTable+cutNum+j)->to =(cTable+(tmpKtbl->to ))->Val;
0249: (rTable+j)->from=(cTable+(tmpKtbl->from))->Val;
0250: (rTable+j)->to =(cTable+(tmpKtbl->to ))->Val;
0251: tmpKtbl=kTable+(j-1)*cTableCnt+(tmpKtbl->prvNo);
0252: }
0253: /*fromとtoの中点をとる*/
0254: if(cutCnt>1) (rTable+0)->to=((rTable+0)->to+(rTable+1)->from)/2;
0255: for(j=1; j<cutCnt-1; j++){
0256: (rTable+j)->from=(rTable+j-1)->to;
0257: (rTable+j)->to =((rTable+j)->to+(rTable+j+1)->from)/2;
0258: }
0259: (rTable+j)->from=(rTable+j-1)->to;
0260:
0261: /* デバッグリスト*/
0262: /*
0263: printf("---- kTable : cnt-----\n");
0264: for(j=0; j<cutCnt; j++){
0265: printf("%02d : ",j);
0266: for(k=0; k<cTableCnt; k++){
0267: printf("%g ", (kTable+cTableCnt*j+k)->minVar);
0268: }
0269: printf("\n");
0270: }
0271: printf("---- kTable : from,to-----\n");
0272: for(j=0; j<cutCnt; j++){
0273: printf("%02d : ",j);
0274: for(k=0; k<cTableCnt; k++){
0275: printf("(%ld,%ld) ", (kTable+cTableCnt*j+k)->from,
0276: (kTable+cTableCnt*j+k)->to );
0277: }
0278: printf("\n");
0279: }
0280: printf("---- kTable : prvNo-----\n");
0281: for(j=0; j<cutCnt; j++){
0282: printf("%02d : ",j);
0283: for(k=0; k<cTableCnt; k++){
0284: printf("%ld ", (kTable+cTableCnt*j+k)->prvNo);
0285: }
0286: printf("\n");
0287: }
0288: printf("---- rTable : prvNo-----\n");
0289: for(j=0; j<cutCnt; j++){
0290: printf("%g - %g\n",
0291: (rTable+j)->from, (rTable+j)->to);
0292: //(rTable+cutNum+j)->from, (rTable+cutNum+j)->to);
0293: }
0294: printf("=============\n");
0295: */
0296: }
0297:
0298: /*
0299: ===============================================================================
0300: Main Function
0301: ===============================================================================
0302: */
0303: int main(int argc, char *argv[]){
0304: /*============================================================================*/
0305: /* オプション宣言&定義 */
0306: /*============================================================================*/
0307: /*----------------------------------------------------------------------------*/
0308: /* キー項目 */
0309: /*----------------------------------------------------------------------------*/
0310: MssOptKEY optKEY={
0311: OKEY, /* オプションタイプ */
0312: "k", /* キーワード(複数文字は不可) */
0313: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0314: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0315: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0316: 2, /* デフォルト(このオプションが指定されなかったときの動作を指定) */
0317: /* 1:全ての行を異るキー値として扱う */
0318: /* 2:全ての行を同じキー値として扱う) */
0319: KEYT, /* このオプションのタイトル(Helpで表示) */
0320: KEYC /* このオプションのコメント(Helpで表示) */
0321: };
0322:
0323: /*----------------------------------------------------------------------------*/
0324: /* 対象項目 */
0325: /*----------------------------------------------------------------------------*/
0326: MssOptFLD optFLD={
0327: OFLD, /* オプションタイプ */
0328: "f", /* キーワード(複数文字は不可) */
0329: 1, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0330: MssFieldMaxCnt, /* 指定可能な最大項目数 */
0331: "i", /* 対象とする入力データのキーワード(GUIで利用) */
0332: 1, /* 正規表現を許可するかどうか(0:不可,1:可) */
0333: 1, /* 新項目名を指定できるかどうか(0:不可,1:可) */
0334: NULL, /* 項目オプション(%以下)で指定可能な文字 */
0335: /* ex) 指定不可の場合はNULL, "nr": "-f 項目名%rn"の指定可能 */
0336: FLDT, /* このオプションのタイトル(Helpで表示) */
0337: FLDC, /* このオプションのコメント(Helpで表示) */
0338: FLDF /* フラグについての説明(Helpで表示)複数の場合はカンマで区切る */
0339: };
0340:
0341: /*----------------------------------------------------------------------------*/
0342: /* 分割数 */
0343: /*----------------------------------------------------------------------------*/
0344: MssOptINT optNUM={
0345: OINT, /* オプションタイプ */
0346: "n", /* キーワード(複数文字は不可) */
0347: 1, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0348: 0, /* デフォルト(数値として指定) */
0349: 2, /* 最小値 */
0350: 255, /* 最大値 */
0351: NUMT, /* このオプションのタイトル(Helpで表示) */
0352: NUMC /* このオプションのコメント(Helpで表示) */
0353: };
0354:
0355: /*----------------------------------------------------------------------------*/
0356: /* 出力書式 */
0357: /*----------------------------------------------------------------------------*/
0358: MssOptSEL optFMT={
0359: OSEL, /* オプションタイプ */
0360: "F", /* キーワード(複数文字は不可) */
0361: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0362: "0", /* デフォルト(文字列にて) */
0363: "0,1,2",
0364: /* 指定可能な値リスト */
0365: FMTT, /* このオプションのタイトル(Helpで表示) */
0366: FMTC, /* このオプションのコメント(Helpで表示) */
0367: FMTS /* フラグについての説明(Helpで表示)複数の場合はカンマで区切る */
0368: };
0369:
0370: /*----------------------------------------------------------------------------*/
0371: /* バケット計算方法 */
0372: /*----------------------------------------------------------------------------*/
0373: MssOptSEL optTyp={
0374: OSEL, /* オプションタイプ */
0375: "c", /* キーワード(複数文字は不可) */
0376: 0, /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視) */
0377: "cnt", /* デフォルト(文字列にて) */
0378: "cnt,rng",
0379: /* 指定可能な値リスト */
0380: TYPT, /* このオプションのタイトル(Helpで表示) */
0381: TYPC, /* このオプションのコメント(Helpで表示) */
0382: TYPS /* フラグについての説明(Helpで表示)複数の場合はカンマで区切る */
0383: };
0384:
0385: /*----------------------------------------------------------------------------*/
0386: /* 番号逆順フラグ */
0387: /*----------------------------------------------------------------------------*/
0388: MssOptFLG optREV={
0389: OFLG, /* オプションタイプ */
0390: "r", /* キーワード(複数文字は不可) */
0391: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0392: REVT, /* このオプションのタイトル(Helpで表示) */
0393: REVC /* このオプションのコメント(Helpで表示) */
0394: };
0395:
0396: /*----------------------------------------------------------------------------*/
0397: /* 入力ファイル */
0398: /*----------------------------------------------------------------------------*/
0399: MssOptINF optINF={
0400: OINF, /* オプションタイプ */
0401: "i", /* キーワード(複数文字は不可) */
0402: 0, /* 0:オプション, 1:必須 */
0403: 1, /* 指定可能の最大ファイル数 */
0404: 0, /*1:file not foundのエラーで終了しない 0:する */
0405: INFT, /* このオプションのタイトル(Helpで表示) */
0406: INFC /* このオプションのコメント(Helpで表示) */
0407: };
0408:
0409: /*----------------------------------------------------------------------------*/
0410: /* 出力ファイル */
0411: /*----------------------------------------------------------------------------*/
0412: MssOptOTF optOTF={
0413: OOTF, /* オプションタイプ */
0414: "o", /* キーワード(複数文字は不可) */
0415: 0, /* 0:オプション, 1:必須 */
0416: OTFT, /* このオプションのタイトル(Helpで表示) */
0417: OTFC /* このオプションのコメント(Helpで表示) */
0418: };
0419:
0420: /*----------------------------------------------------------------------------*/
0421: /* 圧縮出力 */
0422: /*----------------------------------------------------------------------------*/
0423: MssOptFLG optZIP={
0424: OFLG, /* オプションタイプ */
0425: "z", /* キーワード(複数文字は不可) */
0426: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0427: ZIPT, /* このオプションのタイトル(Helpで表示) */
0428: ZIPC /* このオプションのコメント(Helpで表示) */
0429: };
0430:
0431: /*----------------------------------------------------------------------------*/
0432: /* plain text */
0433: /*----------------------------------------------------------------------------*/
0434: MssOptFLG optTXT={
0435: OFLG, /* オプションタイプ */
0436: "t", /* キーワード(複数文字は不可) */
0437: 0, /* デフォルト(基本的には0) 常にonにしたいときは1にする */
0438: TXTT, /* このオプションのタイトル(Helpで表示) */
0439: TXTC /* このオプションのコメント(Helpで表示) */
0440: };
0441:
0442: /*----------------------------------------------------------------------------*/
0443: /* ワークファイル用ディレクトリ名 */
0444: /*----------------------------------------------------------------------------*/
0445: MssOptSTR optTMP={
0446: OSTR, /* オプションタイプ */
0447: "T", /* キーワード(複数文字は不可) */
0448: 0, /* 0:オプション, 1:必須 */
0449: MssTempDir, /* デフォルト */
0450: 1, /* 文字列の最小長 */
0451: MssFileNameMaxLen, /* 文字列の最大長 */
0452: TMPT, /* このオプションのタイトル(Helpで表示) */
0453: TMPC /* このオプションのコメント(Helpで表示) */
0454: };
0455:
0456: /*----------------------------------------------------------------------------*/
0457: /* オプションをまとめる */
0458: /*----------------------------------------------------------------------------*/
0459: void *opt[]={&optKEY,&optFLD,&optNUM,&optFMT,&optTyp,&optREV,
0460: &optINF,&optOTF,&optZIP,&optTXT,&optTMP,NULL};
0461:
0462: /*============================================================================*/
0463: /* 変数宣言&定義 */
0464: /*============================================================================*/
0465: struct mssHeader *hdi; /* 入力ファイル用<head>タグ格納構造体*/
0466: struct mssHeader *hdo; /* 出力ファイル用<head>タグ格納構造体*/
0467: struct mssFPR *fpr; /* 入力ファイル構造体 */
0468: struct mssFPW *fpw; /* 出力ファイル構造体 */
0469: struct mssFldRecKey *frk=NULL;/* キーバッファ構造体 */
0470: struct mssFields *sf; /* ソート項目構造体 */
0471: int sorted; /*ソート済チェック用 */
0472:
0473: char *vstr;
0474: double val;
0475: int num; /*出力するバケット番号*/
0476: int *cutCnts; /*項目毎の実際のバケット数*/
0477: char *bufStr;
0478: double bufNum;
0479: double *max;
0480: double *min;
0481: double rng;
0482: int i,j,k;
0483:
0484: /*----------------------------------------------------------------------------*/
0485: /* 前処理 */
0486: /*----------------------------------------------------------------------------*/
0487: mssInit(argc,argv,&comHelp); /* シグナル処理などの初期化 */
0488: mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ */
0489: mssSetOption(opt,argc,argv); /* コマンドオプションの設定 */
0490: fpr=mssOpenFPR(optINF.str,4); /* 入力ファイルオープン */
0491: hdi=mssReadHeader(fpr); /* ヘッダの読み込み */
0492: mssSetOptKey(&optKEY, hdi); /* -k 項目をヘッダー項目に関連づける */
0493: mssSetOptFld(&optFLD, hdi); /* -f 項目をヘッダー項目に関連づける */
0494:
0495: /*ソート項目の作成*/
0496: sf=mssInitFields();
0497: mssAddFieldsByFields(sf,optKEY.flds); /* -k 項目をソート項目としてセット */
0498: mssSetFieldsSortPriority(sf); /* ソート優先順位番号を登録順にふる */
0499: sorted=mssChkSorted(sf,hdi); /* ソート済かチェック */
0500:
0501: /*mssShowFields(sf);*/
0502: /*mssShowOption(opt);*/
0503: /*mssShowHeader(hdi);*/
0504:
0505: /*----------------------------------------------------------------------------*/
0506: /*出力ヘッダーの作成と出力 */
0507: /*----------------------------------------------------------------------------*/
0508: /*出力ヘッダーの初期化(タイトル等のコピー)*/
0509: hdo=mssInitCpyHeader(hdi);
0510:
0511: /*入力ヘッダの全項目を追加*/
0512: mssAddFieldsByFields(hdo->flds,hdi->flds);
0513:
0514: /*新項目名を追加する*/
0515: mssAddFieldsByStrList(hdo->flds,optFLD.newNam,optFLD.cnt);
0516:
0517: /*ソートする必要があるならばsfのソート情報を反映*/
0518: if(!sorted){
0519: mssSetFieldsSort(hdo->flds,sf);
0520: }
0521:
0522: /*標準出力オープン+ヘッダーの出力*/
0523: fpw=mssOpenFPW(optOTF.str,optZIP.set,0);
0524: mssWriteHeader(hdo, fpw);
0525:
0526: /*----------------------------------------------------------------------------*/
0527: /*メインルーチン */
0528: /*----------------------------------------------------------------------------*/
0529: /*ソートが必用ならばソートしてソート済みファイルとしてオープン*/
0530: if(!sorted){
0531: fpr=mssReopenFPRsort(fpr,4,sf,hdi->flds->cnt,optTMP.str);
0532: }
0533:
0534: rTables=mssMalloc(optFLD.flds->cnt*sizeof(struct rTbl *),"xtbucket");
0535: cutCnts=mssMalloc(optFLD.flds->cnt*sizeof(int),"xtbucket");
0536:
0537: /*FRK構造体の初期化*/
0538: frk=mssInitFRK(hdi->flds->cnt, &optKEY,optTMP.str);
0539:
0540: while(1){ /*loop by key*/
0541: /*データ読み込み*/
0542: if(EOF==mssReadFRK(fpr,frk)) break;
0543:
0544: /*範囲均等化分割(rng)*/
0545: if( strcmp("rng",optTyp.str)==0 ){
0546: max=mssMalloc(optFLD.flds->cnt*sizeof(double),"rng1");
0547: min=mssMalloc(optFLD.flds->cnt*sizeof(double),"rng2");
0548: for(i=0; i<optFLD.flds->cnt; i++){
0549: *(max+i)=-DBL_MAX;
0550: *(min+i)= DBL_MAX;
0551: }
0552:
0553: mssSeekTopFRK(frk);
0554: while( EOF != mssReadFldRecFRK(frk) ){
0555: /*最大値、最小値をセットする*/
0556: for(i=0; i<optFLD.flds->cnt; i++){
0557: bufStr=*(frk->pnt+MssFlds2num(optFLD.flds,i));
0558: if(MssIsNull(bufStr)) continue;
0559: bufNum=atof(bufStr);
0560: if( *(max+i)<bufNum ) *(max+i)=bufNum;
0561: if( *(min+i)>bufNum ) *(min+i)=bufNum;
0562: }
0563: }
0564:
0565: /*rTableメモリアロケーション*/
0566: for(i=0; i<optFLD.flds->cnt; i++){
0567: if( *(max+i)==DBL_MAX || *(min+i)==-DBL_MAX ){
0568: *(rTables+i)=NULL;
0569: *(cutCnts+i)=0; /*カット数のセット*/
0570: }else if( *(max+i) == *(min+i) ){
0571: *(rTables+i) = (struct rTbl *)mssMalloc(
0572: 1*sizeof(struct rTbl),"calOptCutP");
0573: ((*(rTables+i))+0)->from=*(min+i);
0574: ((*(rTables+i))+0)->to =*(max+i);
0575: *(cutCnts+i)=1; /*カット数のセット*/
0576: }else{
0577: *(rTables+i) = (struct rTbl *)mssMalloc(
0578: optNUM.val*sizeof(struct rTbl),"calOptCutP");
0579: rng=( *(max+i) - *(min+i) )/(double)optNUM.val;
0580: for(j=0; j<optNUM.val; j++){
0581: (*(rTables+i)+j)->from=*(min+i)+rng*j;
0582: if(j==optNUM.val-1) (*(rTables+i)+j)->to =*(max+i);
0583: else (*(rTables+i)+j)->to =*(min+i)+rng*(j+1);
0584: }
0585: *(cutCnts+i)=optNUM.val; /*カット数のセット*/
0586: }
0587: }
0588: mssFree(max);
0589: mssFree(min);
0590:
0591: /*件数均等化分割(cnt)*/
0592: }else{
0593: for(i=0; i<optFLD.flds->cnt; i++){
0594: /*データをcTableにセット*/
0595: cTableCnt=0;
0596: cTableMaxCnt=0;
0597: cTable=setcTable(frk,MssFlds2num(optFLD.flds,i));
0598:
0599: /*最適カットポイントを求める*/
0600: calOptCutPoint(optNUM.val);
0601:
0602: /*カット数のセット*/
0603: *(cutCnts+i)=cutCnt;
0604:
0605: /*rTableの保存*/
0606: *(rTables+i)=rTable;
0607:
0608: /*領域開放*/
0609: mssFree(cTable);
0610: mssFree(kTable);
0611: mssFree(sTable);
0612: }
0613: }
0614:
0615: /*出力*/
0616: mssSeekTopFRK(frk);
0617: while( EOF != mssReadFldRecFRK(frk) ){
0618: mssGV.inCnt++;
0619: mssWriteFld(frk->pnt,frk->fldCnt,"",fpw);
0620: mssGV.outCnt++;
0621:
0622: for(i=0; i<optFLD.flds->cnt; i++){
0623: mssWriteDlm(fpw);
0624: vstr=*(frk->pnt+MssFlds2num(optFLD.flds,i));
0625: if(MssIsNull(vstr) || *(cutCnts+i) == 0){
0626: mssWriteNull(fpw);
0627: }else{
0628: val=atof(vstr);
0629: for(k=0; k<*(cutCnts+i)-1; k++){
0630: if( val>=(*(rTables+i)+k)->from && val<(*(rTables+i)+k)->to ){
0631: break;
0632: }
0633: }
0634:
0635: if(optREV.set)num=*(cutCnts+i)-k-1;
0636: else num=k;
0637: if(*optFMT.str=='0'){
0638: mssWriteInt(num+1,fpw);
0639: }else if(*optFMT.str=='1'){
0640: mssWriteDbl((*(rTables+i)+k)->from,fpw);
0641: mssWriteStr("_",fpw);
0642: mssWriteDbl((*(rTables+i)+k)->to ,fpw);
0643: }else{
0644: mssWriteInt(num+1,fpw);
0645: mssWriteStr(":",fpw);
0646: mssWriteDbl((*(rTables+i)+k)->from,fpw);
0647: mssWriteStr("_",fpw);
0648: mssWriteDbl((*(rTables+i)+k)->to ,fpw);
0649: }
0650: }
0651: }
0652: mssWriteRet(fpw);
0653: }
0654: for(i=0; i<optFLD.flds->cnt; i++){
0655: mssFree(*(rTables+i));
0656: }
0657: }
0658:
0659: /*領域開放*/
0660: mssFree(rTables);
0661: mssFree(cutCnts);
0662: mssFreeFRK(frk);
0663:
0664: /*----------------------------------------------------------------------------*/
0665: /*フッター出力&終了処理 */
0666: /*----------------------------------------------------------------------------*/
0667: /*printf("allocCnt=%d\n",getAllocCnt());*/
0668: mssWriteFooter(fpw); /* フッターの出力 */
0669: mssCloseFPR(fpr); /* 入力ファイルのクローズ */
0670: mssCloseFPW(fpw); /* 出力ファイルのクローズ */
0671: mssFreeFields(sf); /* ソート項目構造体の領域開放 */
0672: mssFreeHeader(hdi); /* 入力ヘッダ領域開放 */
0673: mssFreeHeader(hdo); /* 出力ヘッダ領域開放 */
0674: mssFreeOption(opt); /* オプション領域開放 */
0675: mssShowEndMsg(); /* 完了メッセージ */
0676: mssEnd(mssExitSuccess); /* 終了 */
0677: return(0); /* to avoid warning message */
0678: }