Annotation of OpenXM/src/ox_cdd/ox_sres.c, Revision 1.1
1.1 ! noro 1: /* $Id: ox_sres.c,v 1.12 2005/02/03 06:04:18 fujiwara Exp $ */
! 2:
! 3: #include <stdio.h>
! 4: #include <stdlib.h>
! 5: #include <string.h>
! 6:
! 7: #if defined GMPRATIONAL
! 8: #include "gmp.h"
! 9: #define __GMP_FAKE_H__
! 10: #else
! 11: #define dd_almostzero 1.0E-7
! 12: #include <math.h>
! 13: #endif
! 14:
! 15: #include "ox_toolkit.h"
! 16:
! 17: #if defined GMPRATIONAL
! 18: typedef mpq_t mytype;
! 19: #else /* built-in C double */
! 20: typedef double mytype[1];
! 21: #endif
! 22:
! 23: typedef enum {
! 24: dd_LPnone=0, dd_LPmax, dd_LPmin
! 25: } dd_LPObjectiveType;
! 26:
! 27: OXFILE *fd_rw;
! 28:
! 29: #define INIT_S_SIZE 2048
! 30: #define EXT_S_SIZE 2048
! 31:
! 32: static int stack_size = 0;
! 33: static int stack_pointer = 0;
! 34: static cmo **stack = NULL;
! 35: extern int debug_print;
! 36:
! 37: void init_cdd(void);
! 38: int **redcheck(int row,int col,int **matrix,int *presult_row);
! 39: mytype *lpsolve(dd_LPObjectiveType type,int row,int col,int **matrix,int *obj);
! 40: int mvol(int nVar,int *Spt1stIdx,int **Spt);
! 41:
! 42: void dprint( int level, char *string )
! 43: {
! 44: if( debug_print >= level ){
! 45: printf( string );
! 46: fflush( stdout );
! 47: }
! 48: }
! 49:
! 50: #define LP_Q 0
! 51: #define LP_I 1
! 52: #define LP_MAX 0
! 53: #define LP_MIN 1
! 54: #define LP_MAXMIN 2
! 55:
! 56: int initialize_stack()
! 57: {
! 58: stack_pointer = 0;
! 59: stack_size = INIT_S_SIZE;
! 60: stack = MALLOC(stack_size*sizeof(cmo*));
! 61: return 0;
! 62: }
! 63:
! 64: static int extend_stack()
! 65: {
! 66: int size2 = stack_size + EXT_S_SIZE;
! 67: cmo **stack2 = MALLOC(size2*sizeof(cmo*));
! 68: memcpy(stack2, stack, stack_size*sizeof(cmo *));
! 69: free(stack);
! 70: stack = stack2;
! 71: stack_size = size2;
! 72: return 0;
! 73: }
! 74:
! 75: int push(cmo* m)
! 76: {
! 77: stack[stack_pointer] = m;
! 78: stack_pointer++;
! 79: if(stack_pointer >= stack_size) {
! 80: extend_stack();
! 81: }
! 82: return 0;
! 83: }
! 84:
! 85: cmo* pop()
! 86: {
! 87: if(stack_pointer > 0) {
! 88: stack_pointer--;
! 89: return stack[stack_pointer];
! 90: }
! 91: return new_cmo_null();
! 92: }
! 93:
! 94: void pops(int n)
! 95: {
! 96: stack_pointer -= n;
! 97: if(stack_pointer < 0) {
! 98: stack_pointer = 0;
! 99: }
! 100: }
! 101:
! 102: #define OX_SRES_VERSION 0x11121400
! 103: #define ID_STRING "2004/07/23 07:08:00"
! 104:
! 105: int sm_mathcap()
! 106: {
! 107: mathcap_init(OX_SRES_VERSION, ID_STRING, "ox_sres", NULL, NULL);
! 108: push((cmo*)oxf_cmo_mathcap(fd_rw));
! 109: return 0;
! 110: }
! 111:
! 112: int sm_popCMO()
! 113: {
! 114: cmo* m = pop();
! 115:
! 116: if(m != NULL) {
! 117: send_ox_cmo(fd_rw, m);
! 118: return 0;
! 119: }
! 120: return SM_popCMO;
! 121: }
! 122:
! 123: cmo_error2 *make_error2(int code)
! 124: {
! 125: return (cmo_error2 *) new_cmo_int32(-1);
! 126: }
! 127:
! 128: int get_i()
! 129: {
! 130: cmo *c = pop();
! 131: if(c->tag == CMO_INT32) {
! 132: return ((cmo_int32 *)c)->i;
! 133: }else if(c->tag == CMO_ZZ) {
! 134: return mpz_get_si(((cmo_zz *)c)->mpz);
! 135: }
! 136: make_error2(-1);
! 137: return 0;
! 138: }
! 139:
! 140: char *get_str()
! 141: {
! 142: cmo *c = pop();
! 143: if(c->tag == CMO_STRING) {
! 144: return ((cmo_string *)c)->s;
! 145: }
! 146: make_error2(-1);
! 147: return "";
! 148: }
! 149:
! 150: int cmo2int(cmo *c)
! 151: {
! 152: if(c->tag == CMO_INT32) {
! 153: return ((cmo_int32 *)c)->i;
! 154: }else if(c->tag == CMO_ZZ) {
! 155: return mpz_get_si(((cmo_zz *)c)->mpz);
! 156: } else if(c->tag == CMO_NULL){
! 157: return 0;
! 158: }
! 159:
! 160: return 0;
! 161: }
! 162:
! 163: cmo *matrix2cmo( int **matrix, int row, int col )
! 164: {
! 165: cmo_list *result,*work;
! 166: cmo *tmp;
! 167: int i,j;
! 168:
! 169: result = new_cmo_list();
! 170: for(i=0;i<row;i++){
! 171:
! 172: work = new_cmo_list();
! 173: for(j=0;j<col;j++){
! 174: if( matrix[i][j] != 0 ){
! 175: tmp = (cmo*) new_cmo_zz_set_si( matrix[i][j] );
! 176: } else {
! 177: tmp = (cmo*) new_cmo_zero();
! 178: }
! 179: work = list_append( work, tmp );
! 180: }
! 181: result = list_append( result, (cmo*)work );
! 182:
! 183: }
! 184:
! 185: return (cmo *)result;
! 186: }
! 187:
! 188: int mytype2int( mytype a, int i )
! 189: {
! 190: #if defined GMPRATIONAL
! 191: /* How to round "a" depends on "i".
! 192: if i < 0, then the rounding style is "floor".
! 193: if i = 0, then the rounding style is "truncate".
! 194: if i > 0, then the rounding style is "ceil". */
! 195: int ret;
! 196: mpz_t q;
! 197: mpz_init(q);
! 198:
! 199: if( i < 0 ){
! 200: mpz_fdiv_q( q, mpq_numref(a), mpq_denref(a) );
! 201: } else if( i > 0 ){
! 202: mpz_cdiv_q( q, mpq_numref(a), mpq_denref(a) );
! 203: } else {
! 204: mpz_tdiv_q( q, mpq_numref(a), mpq_denref(a) );
! 205: }
! 206:
! 207: ret = mpz_get_si( q );
! 208: mpz_clear( q );
! 209: return ret;
! 210: #else
! 211: /* How to round "a" depends on "i".
! 212: if i < 0, then the rounding style is "floor".
! 213: if i = 0, then the rounding style is "near".
! 214: if i > 0, then the rounding style is "ceil". */
! 215: if( i < 0 ){
! 216: return floor( *a + dd_almostzero );
! 217: } else if( i == 0 ){
! 218: return (int)( *a + 0.5 );
! 219: } else {
! 220: return ceil( *a - dd_almostzero );
! 221: }
! 222: #endif
! 223: }
! 224:
! 225: void my_redcheck(void)
! 226: {
! 227: int row,col,result_row;
! 228: int i,j;
! 229: cmo *a,*b,*c;
! 230: int **matrix,**result;
! 231:
! 232: pop(); /* for argc */
! 233: row = get_i(); /* row size */
! 234: col = get_i(); /* col size */
! 235:
! 236: a = pop();
! 237:
! 238: matrix = MALLOC( row * sizeof(int*) );
! 239: for(i=0;i<row;i++){
! 240: matrix[i] = MALLOC( col * sizeof(int) );
! 241: }
! 242:
! 243: for(i=0;i<row;i++){
! 244: b = list_nth( (cmo_list*)a, i );
! 245: for(j=0;j<col;j++){
! 246: c = list_nth( (cmo_list*)b, j );
! 247: matrix[i][j] = cmo2int( c );
! 248: }
! 249: }
! 250:
! 251: dprint(1,"redcheck...");
! 252: result = redcheck(row,col,matrix,&result_row);
! 253: dprint(1,"done\n");
! 254:
! 255: push( matrix2cmo(result,result_row,col) );
! 256: }
! 257:
! 258: void my_lpsolve( int resulttype, int index )
! 259: {
! 260: int row,col;
! 261: int i,j;
! 262: cmo *a,*b,*c;
! 263: cmo_list* ret;
! 264: int **matrix,*object;
! 265: int lpmax,lpmin;
! 266: mytype *tmp;
! 267: cmo *cmomin,*cmomax;
! 268:
! 269: pop(); /* for argc */
! 270: row = get_i(); /* row size */
! 271: col = get_i(); /* col size */
! 272:
! 273: matrix = MALLOC( row * sizeof(int*) );
! 274: for(i=0;i<row;i++){
! 275: matrix[i] = MALLOC( col * sizeof(int) );
! 276: }
! 277:
! 278: a = pop();
! 279:
! 280: /* For matrix */
! 281: for(i=0;i<row;i++){
! 282: b = list_nth( (cmo_list*)a, i );
! 283: for(j=0;j<col;j++){
! 284: c = list_nth( (cmo_list*)b, j );
! 285: matrix[i][j] = cmo2int( c );
! 286: }
! 287: }
! 288:
! 289: /* For object */
! 290: object = MALLOC( col * sizeof(int) );
! 291: a = pop();
! 292:
! 293: for(i=0;i<col;i++){
! 294: c = list_nth( (cmo_list*)a, i );
! 295:
! 296: object[i] = cmo2int( c );
! 297: }
! 298:
! 299: if( index == LP_MAX ){
! 300: dprint( 1, "lpsolve(max)...");
! 301: } else if( index == LP_MIN ){
! 302: dprint( 1, "lpsolve(min)...");
! 303: } else if( LP_MAXMIN ){
! 304: dprint( 1, "lpsolve(maxmin)...");
! 305: }
! 306:
! 307: if( index == LP_MAX || index == LP_MAXMIN ){
! 308: tmp = lpsolve( dd_LPmax, row, col, matrix, object );
! 309: if( resulttype == LP_I ){
! 310: lpmax = mytype2int( *tmp, -1 );
! 311: if( lpmax == 0 ){
! 312: cmomax = (cmo*) new_cmo_zero();
! 313: } else {
! 314: cmomax = (cmo*) new_cmo_zz_set_si( lpmax );
! 315: }
! 316: } else if( resulttype == LP_Q ){
! 317: #if defined GMPRATIONAL
! 318: if( mpz_cmp_si( mpq_numref( *tmp ), 0 ) == 0 ){
! 319: cmomax = (cmo*) new_cmo_zero();
! 320: } else {
! 321: cmomax = (cmo*) new_cmo_qq_set_mpz( mpq_numref( *tmp ), mpq_denref( *tmp ) );
! 322: }
! 323: #else
! 324: cmomax = (cmo*) new_cmo_double( *tmp[0] );
! 325: #endif
! 326: }
! 327: #if defined GMPRATIONAL
! 328: mpq_clear( *tmp );
! 329: #endif
! 330: }
! 331:
! 332: if( index == LP_MIN || index == LP_MAXMIN ){
! 333: tmp = lpsolve( dd_LPmin, row, col, matrix, object );
! 334: if( resulttype == LP_I ){
! 335: lpmin = mytype2int( *tmp, 1 );
! 336: if( lpmin == 0 ){
! 337: cmomin = (cmo*) new_cmo_zero();
! 338: } else {
! 339: cmomin = (cmo*) new_cmo_zz_set_si( lpmin );
! 340: }
! 341: } else if( resulttype == LP_Q ){
! 342: #if defined GMPRATIONAL
! 343: if( mpz_cmp_si( mpq_numref( *tmp ), 0 ) == 0 ){
! 344: cmomin = (cmo*) new_cmo_zero();
! 345: } else {
! 346: cmomin = (cmo*) new_cmo_qq_set_mpz( mpq_numref( *tmp ), mpq_denref( *tmp ) );
! 347: }
! 348: #else
! 349: cmomin = (cmo*) new_cmo_double( *tmp[0] );
! 350: #endif
! 351: }
! 352: #if defined GMPRATIONAL
! 353: mpq_clear( *tmp );
! 354: #endif
! 355:
! 356: }
! 357:
! 358: if( index == LP_MAX ){
! 359: push( cmomax );
! 360: } else if( index == LP_MIN ){
! 361: push( cmomin );
! 362: } else if( index == LP_MAXMIN ){
! 363: ret = new_cmo_list();
! 364: ret = list_append( ret, cmomin );
! 365: ret = list_append( ret, cmomax );
! 366: push( (cmo*) ret );
! 367: }
! 368:
! 369: }
! 370:
! 371: void my_mvol(void)
! 372: {
! 373: int var,pts,result;
! 374: int i,j,k,n;
! 375: cmo *a,*b,*c,*d;
! 376: int *spt1i,**matrix;
! 377:
! 378: pts = 0;
! 379:
! 380: pop(); /* for argc */
! 381: var = get_i(); /* row size */
! 382:
! 383: spt1i = MALLOC( (var+1) * sizeof(int) );
! 384:
! 385: a = pop();
! 386: for(i=0;i<var;i++){
! 387: c = list_nth( (cmo_list*)a, i );
! 388: spt1i[i] = cmo2int( c );
! 389: pts += spt1i[i];
! 390: }
! 391: spt1i[var] = pts;
! 392:
! 393:
! 394: matrix = MALLOC( pts * sizeof(int *) );
! 395: for(i=0;i<pts;i++){
! 396: matrix[i] = MALLOC( var * sizeof(int) );
! 397: }
! 398:
! 399: a = pop();
! 400: for(i=n=0;i<var;i++){
! 401: b = list_nth( (cmo_list*)a, i );
! 402: for(j=0;j<spt1i[i];j++,n++){
! 403: c = list_nth( (cmo_list*)b, j );
! 404: for(k=0;k<var;k++){
! 405: d = list_nth( (cmo_list*)c, k );
! 406: matrix[n][k] = cmo2int( d );
! 407: }
! 408: }
! 409: }
! 410:
! 411: dprint( 1, "mvol...");
! 412: result = mvol( var, spt1i, matrix );
! 413: dprint( 1, "done\n");
! 414:
! 415: if( result == 0 ){
! 416: push( (cmo*) new_cmo_zero() );
! 417: } else {
! 418: push( (cmo*) new_cmo_zz_set_si( result ) );
! 419: }
! 420:
! 421: }
! 422:
! 423: int sm_executeFunction()
! 424: {
! 425: cmo_string *func = (cmo_string *)pop();
! 426: if(func->tag != CMO_STRING) {
! 427: printf("sm_executeFunction : func->tag is not CMO_STRING");fflush(stdout);
! 428: push((cmo*)make_error2(0));
! 429: return -1;
! 430: }
! 431:
! 432: if(strcmp(func->s, "redcheck" ) == 0) {
! 433: my_redcheck();
! 434: return 0;
! 435: } else if( strcmp( func->s, "ilpmax" ) == 0 ){
! 436: my_lpsolve(LP_I,LP_MAX);
! 437: return 0;
! 438: } else if( strcmp( func->s, "ilpmin" ) == 0 ){
! 439: my_lpsolve(LP_I,LP_MIN);
! 440: return 0;
! 441: } else if( strcmp( func->s, "ilpmaxmin" ) == 0 ){
! 442: my_lpsolve(LP_I,LP_MAXMIN);
! 443: return 0;
! 444: } else if( strcmp( func->s, "lpmax" ) == 0 ){
! 445: my_lpsolve(LP_Q,LP_MAX);
! 446: return 0;
! 447: } else if( strcmp( func->s, "lpmin" ) == 0 ){
! 448: my_lpsolve(LP_Q,LP_MIN);
! 449: return 0;
! 450: } else if( strcmp( func->s, "lpmaxmin" ) == 0 ){
! 451: my_lpsolve(LP_Q,LP_MAXMIN);
! 452: return 0;
! 453: } else if( strcmp( func->s, "mvol" ) == 0 ){
! 454: my_mvol();
! 455: return 0;
! 456: } else if( strcmp( func->s, "debugprint" ) == 0 ){
! 457: pop();
! 458: debug_print = get_i();
! 459: return 0;
! 460: } else if( strcmp( func->s, "exit" ) == 0 ){
! 461: pop();
! 462: exit(0);
! 463: return 0;
! 464: } else {
! 465: push((cmo*)make_error2(0));
! 466: return -1;
! 467: }
! 468: }
! 469:
! 470: int receive_and_execute_sm_command()
! 471: {
! 472: int code = receive_int32(fd_rw);
! 473: switch(code) {
! 474: case SM_popCMO:
! 475: sm_popCMO();
! 476: break;
! 477: case SM_executeFunction:
! 478: sm_executeFunction();
! 479: break;
! 480: case SM_mathcap:
! 481: sm_mathcap();
! 482: break;
! 483: case SM_setMathCap:
! 484: pop();
! 485: break;
! 486: default:
! 487: printf("receive_and_execute_sm_command : code=%d\n",code);fflush(stdout);
! 488: break;
! 489: }
! 490: return 0;
! 491: }
! 492:
! 493: int receive()
! 494: {
! 495: int tag;
! 496:
! 497: tag = receive_ox_tag(fd_rw);
! 498: switch(tag) {
! 499: case OX_DATA:
! 500: push(receive_cmo(fd_rw));
! 501: break;
! 502: case OX_COMMAND:
! 503: receive_and_execute_sm_command();
! 504: break;
! 505: default:
! 506: printf("receive : tag=%d\n",tag);fflush(stdout);
! 507: }
! 508: return 0;
! 509: }
! 510:
! 511: int main()
! 512: {
! 513: GC_INIT();
! 514: ox_stderr_init(stderr);
! 515: initialize_stack();
! 516: init_cdd();
! 517:
! 518: fd_rw = oxf_open(3);
! 519: oxf_determine_byteorder_server(fd_rw);
! 520:
! 521: while(1){
! 522: receive();
! 523: }
! 524: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>