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