[BACK]Return to replace.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / kan96xx / Kan

File: [local] / OpenXM / src / kan96xx / Kan / replace.c (download)

Revision 1.2, Sun Jan 16 07:55:41 2000 UTC (24 years, 4 months ago) by takayama
Branch: MAIN
CVS Tags: maekawa-ipv6, RELEASE_20000124, RELEASE_1_1_3, RELEASE_1_1_2
Changes since 1.1: +1 -0 lines

Congratulation of sm1 version 3.* !

/* $OpenXM: OpenXM/src/kan96xx/Kan/replace.c,v 1.2 2000/01/16 07:55:41 takayama Exp $ */
#include <stdio.h>
#include "datatype.h"
#include "extern2.h"

static int badLRule(POLY set[],int num);

POLY mReplace(mm,lSideX,rSideX,sizex,lSideD,rSideD,sized,commutative)
POLY mm;
int lSideX[];
POLY rSideX[];  /* Rule: a=lSideX[i], x_a ---> rSideX[i] */
int sizex;
int lSideD[];   /* Rule: b=lSideD[i], D_b ---> rSideD[i] */
POLY rSideD[];
int sized;
int commutative;
{
/* The function should be tuned by using a table. */
  POLY rp;
  POLY fac;
  int i;
  int j;
  int flag;
  MONOMIAL mp;
  int n;

  mp = mm->m;
  rp = newCell(coeffCopy(mm->coeffp),newMonomial(mp->ringp));
  n = mp->ringp->n;

  /* Multiply backwards. It's faster. */
  for (i=n-1; i>=0; i--) {
    if (mp->e[i].D != 0) {
      flag = 1;
      for (j=0; j<sized; j++) {
	if (lSideD[j] == i) {
	  if (commutative) fac = pPower_poly(rSideD[j],mp->e[i].D);
	  else fac = pPower(rSideD[j],mp->e[i].D);
	  /* if negative, this does not work  well!! */
	  flag = 0;
	  break;
	}
      }
      if (flag) fac = cdd(1,i,mp->e[i].D,mp->ringp);
      if (commutative) rp = ppMult_poly(fac,rp);
      else rp = ppMult(fac,rp);
    }
  }

  for (i=n-1; i>=0; i--) {
    if (mp->e[i].x != 0) {
      flag = 1;
      for (j=0; j<sizex; j++) {
	if (lSideX[j] == i) {
	  if (commutative) fac = pPower_poly(rSideX[j],mp->e[i].x);
	  else fac = pPower(rSideX[j],mp->e[i].x);
	  /* if negative, this does not work well!! */
	  flag = 0;
	  break;
	}
      }
      if (flag) fac = cxx(1,i,mp->e[i].x,mp->ringp);
      if (commutative) rp = ppMult_poly(fac,rp);
      else rp = ppMult(fac,rp);
    }
  }

  return(rp);
}

/*
  lRule[i] ---> rRule[i]
*/
POLY replace(f,lRule,rRule,num)
POLY f;
POLY lRule[];  /* lRule[i] must be x0 or ... or D{N-1} */
POLY rRule[];
int num;
{
  POLY rSideX[N0];
  POLY rSideD[N0];
  int  lSideX[N0];
  int  lSideD[N0];
  int i,j,size;
  int sizex,sized;
  POLY rp;
  int n;

  /***printf("f=%s\n",POLYToString(f,'*',0));
  for (i=0; i<num; i++) {
    printf("%s --> %s\n",POLYToString(lRule[i],'*',0),
	   POLYToString(rRule[i],'*',0));
  }
  printf("\n"); ***/
  
  if (f ISZERO) return(ZERO);
  sizex = sized = 0;
  if (badLRule(lRule,num)) {
    warningPoly("replace(): lRule must be a variable.");
    return(ZERO);
  }
  n = f->m->ringp->n;
  /* x-part */
  for (i=0; i<n; i++) {
    for (j=0; j<num; j++) {
      if (lRule[j]->m->e[i].x == 1) {
	lSideX[sizex] = i;
	rSideX[sizex] = rRule[j];
	sizex++;
	if (sizex >= n) {
	  warningPoly(" replace(): too many x-rules . ");
	  sizex--;
	}
	break;
      }
    }
  }
  /* D-part */
  for (i=0; i<n; i++) {
    for (j=0; j<num; j++) {
      if (lRule[j]->m->e[i].D == 1) {
	lSideD[sized] = i;
	rSideD[sized] = rRule[j];
	sized++;
	if (sized >= n) {
	  warningPoly(" replacen(): too many D-rules . ");
	  sized--;
	}
	break;
      }
    }
  }

  rp = ZERO;
  if (f ISZERO) return(ZERO);
  while(f != POLYNULL) {
    rp = ppAddv(rp,mReplace(f,lSideX,rSideX,sizex,lSideD,rSideD,sized,0));
    f = f->next;
  }
  return(rp);
}
      

/* For the dirty trick of mpMult_difference */  
POLY replace_poly(f,lRule,rRule,num)  
POLY f;
POLY lRule[];  /* lRule[i] must be x0 or ... or D{N-1} */
POLY rRule[];
int num;
{
  POLY rSideX[N0];
  POLY rSideD[N0];
  int  lSideX[N0];
  int  lSideD[N0];
  int i,j,size;
  int sizex,sized;
  POLY rp;
  int n;

  /***printf("f=%s\n",POLYToString(f,'*',0));
  for (i=0; i<num; i++) {
    printf("%s --> %s\n",POLYToString(lRule[i],'*',0),
	   POLYToString(rRule[i],'*',0));
  }
  printf("\n"); ***/
  
  if (f ISZERO) return(ZERO);
  sizex = sized = 0;
  if (badLRule(lRule,num)) {
    warningPoly("replace(): lRule must be a variable.");
    return(ZERO);
  }
  n = f->m->ringp->n;
  /* x-part */
  for (i=0; i<n; i++) {
    for (j=0; j<num; j++) {
      if (lRule[j]->m->e[i].x == 1) {
	lSideX[sizex] = i;
	rSideX[sizex] = rRule[j];
	sizex++;
	if (sizex >= n) {
	  warningPoly(" replace(): too many x-rules . ");
	  sizex--;
	}
	break;
      }
    }
  }
  /* D-part */
  for (i=0; i<n; i++) {
    for (j=0; j<num; j++) {
      if (lRule[j]->m->e[i].D == 1) {
	lSideD[sized] = i;
	rSideD[sized] = rRule[j];
	sized++;
	if (sized >= n) {
	  warningPoly(" replacen(): too many D-rules . ");
	  sized--;
	}
	break;
      }
    }
  }

  rp = ZERO;
  if (f ISZERO) return(ZERO);
  while(f != POLYNULL) {
    rp = ppAddv(rp,mReplace(f,lSideX,rSideX,sizex,lSideD,rSideD,sized,1));
    f = f->next;
  }
  return(rp);
}
      
  
static int badLRule(set,num)
POLY set[];
int num;
{ int i;
  for (i=0; i<num; i++) {
    if (set[0] ISZERO) {
      return(1);
    }
  }
  return(0);
}