Exemplo n.º 1
0
void integ_rekurs( RAT *eqsum, RAT *iesum, int lev )
{ 
    val.den.i = 1;
    
    if (reknum % 1000 == 0) 
    {
        fprintf(prt,".");
        fflush(prt);

        /* 17.01.1994: include logging on file porta.log */
        porta_log(".");
        fflush(logfile);
    }
    reknum++;
    
    if (lev == eqdim) 
    {
        for (ptr = eqar+eqdim; ptr < ubea; ptr += eqrl, eqsum++) 
        {
            I_RAT_sub(*eqsum,*ptr,&val);
            if (val.num != 0)
                return;
        }
        for (ptr = iear+iedim; ptr < ubia; ptr += ierl, iesum++) 
        {
            I_RAT_sub(*iesum,*ptr,&val);
            if (val.num > 0)
                return;
        }
        
        intnum++;
        fprintf(fp,"(%3d) ",intnum);
        for (i = 0; i < eqdim; i++) 
            fprintf(fp,"%i ",integ[i]);
        fprintf(fp,"\n");
    }
    else 
    {
        val.num = lowbds[lev];
        osump = eqsum;
        nsump = eqsum+neq;
        for (ptr = eqar+lev; ptr < ubea; ptr += eqrl,osump++,nsump++) 
        {
            I_RAT_mul(*ptr,val,nsump);
            I_RAT_add(*osump,*nsump,nsump);
        }
        osump = iesum;
        nsump = iesum+nie;
        for (ptr = iear+lev; ptr < ubia; ptr += ierl,osump++,nsump++) 
        {
            I_RAT_mul(*ptr,val,nsump);
            I_RAT_add(*osump,*nsump,nsump);
        }
        
        for (integ[lev]=lowbds[lev]; integ[lev]<upbds[lev]; integ[lev]+=1) 
        {
            integ_rekurs(eqsum+neq,iesum+nie,lev+1);
            osump = eqsum;
            nsump = eqsum+neq;
            for (ptr = eqar+lev; ptr < ubea; ptr += eqrl,nsump++)
                I_RAT_add(*nsump,*ptr,nsump);
            osump = iesum;
            nsump = iesum+nie;
            for (ptr = iear+lev; ptr < ubia; ptr += ierl,nsump++)
                I_RAT_add(*nsump,*ptr,nsump);
        }
        integ_rekurs(eqsum+neq,iesum+nie,lev+1);
    }
}
Exemplo n.º 2
0
void read_eqie( RAT **ar, int dim, int *equa, int *ineq, int *maxrows, int *line,
               char *fname, char in_line[], char *scanned_inline )
/*****************************************************************/
/*
 * Read the INEQUALITY_SECTION into the table "ar".
 * For each (in)equality, the corresponding line of "ar" contains, in this order:
 *    the "dim" coefficients of the variables x1--xn,
 *    the right-hand side,
 *    0 if it was an equation, 1 if it was an inequality.
 * All inequalities are stored as "<=" inequalities.
 * Lines as
 *   "x1 - 1 <= 3 + x2"
 * are interpreted as
 *   "x1 -x2 <= 4"
 */
{
    char *p,*in;
    int i,rs=0,index=0,j,sysrow, numberread,nonempty;
    RAT val;

    sysrow = dim+2; /* row length of array "ar" */
    do 
    {
        nonempty = get_line(fp,fname,in_line,line);
    } 
    while (!nonempty);
    for (i = 0; scan_line(&val,3,dim,*line,
                          fname,in_line,scanned_inline);
         i++) 
    {
        /* 
         * scan_line() reads an inequality into string "scanned_inline",
         * with a little formatting.
         * "val" is not used.
         */
        p = in = scanned_inline;
        rs = 0;     /* rs records the type of inequality,
                     * rs = 0 means: type not yet known. */
        
        /* scan string "scanned_inline" up to '\0' or '#' */
        while (*p != '\0' && *p != '#' ) 
        {
            
            val.den.i = 1;
            val.num = 1;
            if (*p == '-')
                val.num = -1;
        
            /* 
             * If: {+,-} has been read,
             *     or {<,=,>} followed by {x,0,1,..,9} has been read,
             *     or it is the beginning of the line. then ...
             */
            if ( *p == '-' || *p == '+'  || 
                (p == scanned_inline || 
                 (p != scanned_inline && (*(p-1)=='<' || *(p-1)=='=' || *(p-1)=='>')) 
                 && ((*p < 58 && *p > 47) || *p =='x') )     ) 
            {
                numberread = 0;
                if ( *p == '-' || *p == '+')    p++;
                in = p;
                while (*p > 47 && *p < 58)
                    p++;
                if (in != p) 
                {
                    /* in points to a number, p to the next non-number */
                    numberread = 1;
                    val.num *= atoi(in);
                    if (*p == '/') 
                    {
                        p++;
                        in = p;
                        while (*p > 47 && *p < 58) p++;
                        if (p == in)
                            msg("%s, line %i : invalid denominator",
                                fname,*line);
                        if ((val.den.i = atoi(in)) <= 0)
                            msg("%s, line %i : invalid denominator",
                                fname,*line);
                    }   
                } /* if (in != p) */

                if (*p == 'x') 
                {
                    p++;
                    in = p;
                    while (*p > 47 && *p < 58) p++;
                    if (p == in) 
                        msg("%s, line %i : invalid format",fname,*line);
                    index = atoi(in)-1;
                    if (index > dim-1 || index < 0)
                        msg("%s, line %i : only variable names x1,...,xdim allowed",
                            fname,*line);
                }
                /* 
                 * Change by M.S. 1.6.92:
                 * The following four lines of code are changed.
                 *
                 * In the case (*p in {+,-}), 
                 * something like "10 +", but not "x10 +" has been encountered.
                 * In the case (rs==0 && *p in {<,>,>} ),
                 * something like "10 <", but not "x10 <" has been encountered.
                 * In both cases, the number "10" is interpreted as part of
                 * the right-hand side.
                 * But it should be tested, 
                 * whether a number has actually been read.
                 * Otherwise
                 * "x1++x2 <= 20\n"  is interpreted as
                 * "x1+1+x2 <= 20\n".
                 */
                else if (numberread && (*p == '+' || *p == '-'  || 
                          ((rs == 0) && (*p =='<'||*p == '>'||*p == '=')))) 
                {
                    index = dim;
                }
                /* The following four lines mean:
                 * If "<=" or ">=" or "==" has already been read (i.e. rs > 0),
                 * and if p points to the end of the line,
                 * then interpret the number in val as the right hand side.
                 * to be stored in the dim-th position of the current row
                 * of table "ar".
                 */
                else if (numberread && rs && (*(p) == '\0' || *(p) == '#'))  
                {
                    index = dim;
                }
                else 
                    msg("%s, line %i : invalid format",fname,*line);
            } /* if ......... */

            else if ((p != scanned_inline) 
                     && (*p == '<' || *p == '>' || *p == '=')) 
            {
                /* 
                 * Record the type of inequality:
                 * rs = 1   if it is an equation ("=" or "==")
                 * rs = 2   if it is a "<=" inequality (may also be written "=<")
                 * rs = 3   if it is a ">=" inequality (may also be written "=>")
                 */
                if (++rs > 1) 
                    msg("%s, line %i : invalid format",fname,*line);
                if ((*p == '=') && (*(p+1) == '='))
                    p++;
                else if ((*p == '=') && (*(p+1) != '>') && (*(p+1) != '<'));
                else if ((*p == '=' && *(p+1) == '>') ||
                         (*p == '>' && *(p+1) == '=')) 
                {
                    rs++;rs++;
                    p++;
                }
                else if ((*p == '=' && *(p+1) == '<') ||
                         (*p == '<' && *(p+1) == '=')) 
                {
                    rs++; 
                    p++;
                }
                else
                    msg("%s, line %i : invalid format",fname,*line);
                p++;
                index = -1;
            } /* else if < = > */
            
            else 
                msg("%s, line %i : invalid format",fname,*line);
            
            if (index > -1)  
            { /* not "< > =" */ 
                if (index == dim) val.num *= -1;
                if (rs ) 
                    I_RAT_sub(*(*ar+i*sysrow+index),val,*ar+i*sysrow+index);
                else
                    I_RAT_add(*(*ar+i*sysrow+index),val,*ar+i*sysrow+index);
            }
            
        } /* while */
        
        /* transform ">=" into "<=" by multiplying the inequality with -1 */
        if (rs == 3 ) 
        {  /* >= */
            for (j = 0; j <= dim; j++)
                (*ar+i*sysrow+j)->num = -(*ar+i*sysrow+j)->num;
            rs -= 1;
        }
        (*ar+(i+1)*sysrow-1)->num  =  --rs; 
    
        /* 
         * Now rs = 0 if the line was an equation,
         * and rs = 1 if the line was an inequality.
         * The last line stored rs into the "dim+1"th position of ar[i].
         */
        (rs == 1) ? (*ineq)++ : (*equa)++;
        
        if ((*ineq)+(*equa)+2 > *maxrows) 
        {
            *ar = (RAT *) RATallo(*ar,(*maxrows)*(dim+2),(*maxrows+INCR_INSYS_ROW)*(dim+2));
            *maxrows += INCR_INSYS_ROW;
        }
        do 
        {
            nonempty = get_line(fp,fname,in_line,line);
        } 
        while (!nonempty);
    }  /* for i */
}