M2_arrayint M2_makearrayint(int n) { M2_arrayint z = (M2_arrayint)getmem_atomic(sizeofarray(z,n)); z->len = n; //GC_CHECK_CLOBBER(z); return z; /* Note that getmem_atomic returns zeroed memory */ }
M2_string M2_tostringn(char *s, int n) { M2_string p = (M2_string)getmem_atomic(sizeofarray(p,n)); p->len = n; memcpy(p->array,s,n); //GC_CHECK_CLOBBER(p); return p; }
char * M2_tocharstar(M2_string s) { char *p = getmem_atomic(s->len + 1); memcpy(p,s->array,s->len); p[s->len] = 0; //GC_CHECK_CLOBBER(p); return p; }
M2_string M2_join(M2_string x, M2_string y) { M2_string p; p = (M2_string) getmem_atomic(sizeofarray(p,x->len+y->len)); p->len = x->len + y->len; memcpy(p->array,x->array,x->len); memcpy(p->array+x->len,y->array,y->len); //GC_CHECK_CLOBBER(p); return p; }
MonomialOrder *monomialOrderMake(const MonomialOrdering *mo) { MonomialOrder *result; int i, j, nv, this_block; deg_t *wts = NULL; /* Determine the number of variables, the number of blocks, and the location of the component */ int nblocks = 0; int nvars = 0; int hascomponent = 0; for (i = 0; i < mo->len; i++) { struct mon_part_rec_ *t = mo->array[i]; nblocks++; if (t->type == MO_POSITION_DOWN || t->type == MO_POSITION_UP) hascomponent++; else if (t->type == MO_NC_LEX) { // Currently, do nothing. } if (t->type != MO_WEIGHTS) nvars += t->nvars; } nblocks -= hascomponent; /* Now create the blocks, and fill them in. Also fill in the deg vector */ result = getmemstructtype(MonomialOrder *); result->nvars = nvars; result->nslots = 0; result->nblocks = nblocks; result->blocks = (struct mo_block *)getmem(nblocks * sizeof(result->blocks[0])); result->degs = (deg_t *)getmem_atomic(nvars * sizeof(result->degs[0])); if (hascomponent == 0) result->nblocks_before_component = nblocks; this_block = 0; nvars = 0; for (i = 0; i < mo->len; i++) { struct mon_part_rec_ *t = mo->array[i]; if (t->type != MO_WEIGHTS) { if (t->wts == 0) for (j = 0; j < t->nvars; j++) result->degs[nvars++] = 1; else for (j = 0; j < t->nvars; j++) result->degs[nvars++] = t->wts[j]; } else { wts = (deg_t *)getmem_atomic(t->nvars * sizeof(wts[0])); for (j = 0; j < t->nvars; j++) wts[j] = t->wts[j]; } switch (t->type) { case MO_REVLEX: mo_block_revlex(result->blocks + this_block++, t->nvars); break; case MO_GREVLEX: mo_block_grevlex(result->blocks + this_block++, t->nvars); break; case MO_GREVLEX2: mo_block_grevlex2(result->blocks + this_block++, t->nvars); break; case MO_GREVLEX4: mo_block_grevlex4(result->blocks + this_block++, t->nvars); break; case MO_GREVLEX_WTS: mo_block_grevlex_wts(result->blocks + this_block++, t->nvars); break; case MO_GREVLEX2_WTS: mo_block_grevlex2_wts(result->blocks + this_block++, t->nvars); break; case MO_GREVLEX4_WTS: mo_block_grevlex4_wts(result->blocks + this_block++, t->nvars); break; case MO_LEX: mo_block_lex(result->blocks + this_block++, t->nvars); break; case MO_LEX2: mo_block_lex2(result->blocks + this_block++, t->nvars); break; case MO_LEX4: mo_block_lex4(result->blocks + this_block++, t->nvars); break; case MO_WEIGHTS: // if extra weight values are given (more than "nvars", ignore the // rest. mo_block_wt_function( result->blocks + this_block++, (t->nvars <= result->nvars ? t->nvars : result->nvars), wts); break; case MO_LAURENT: mo_block_group_lex(result->blocks + this_block++, t->nvars); break; case MO_LAURENT_REVLEX: mo_block_group_revlex(result->blocks + this_block++, t->nvars); break; case MO_NC_LEX: /* MES */ break; case MO_POSITION_UP: if (--hascomponent == 0) { // Set the information about the component result->component_up = 1; result->nblocks_before_component = this_block; } // mo_block_position_up(result->blocks + this_block); break; case MO_POSITION_DOWN: if (--hascomponent == 0) { // Set the information about the component result->component_up = 0; result->nblocks_before_component = this_block; } // mo_block_position_down(result->blocks + this_block); break; } } /* Go back and fill in the 'slots' information */ /* Now fix the first_exp, first_slot values, and also result->{nslots,nvars}; */ nv = 0; result->nslots = 0; result->nslots_before_component = 0; for (i = 0; i < nblocks; i++) { enum MonomialOrdering_type typ = result->blocks[i].typ; result->blocks[i].first_exp = nv; result->blocks[i].first_slot = result->nslots; nv += result->blocks[i].nvars; result->nslots += result->blocks[i].nslots; if (typ == MO_WEIGHTS) { result->blocks[i].first_exp = 0; /* divide the wt vector by the degree vector */ for (j = 0; j < result->blocks[i].nvars; j++) safe::div_by(result->blocks[i].weights[j], result->degs[j]); ; } else if (typ == MO_GREVLEX_WTS || typ == MO_GREVLEX2_WTS || typ == MO_GREVLEX4_WTS) { result->blocks[i].weights = result->degs + result->blocks[i].first_exp; } if (i == result->nblocks_before_component - 1) { result->nslots_before_component = result->nslots; } } /* Set is_laurent */ result->is_laurent = (int *)getmem_atomic(result->nvars * sizeof(int)); for (i = 0; i < result->nvars; i++) result->is_laurent[i] = 0; for (i = 0; i < result->nblocks; i++) if (result->blocks[i].typ == MO_LAURENT || result->blocks[i].typ == MO_LAURENT_REVLEX) { for (j = 0; j < result->blocks[i].nvars; j++) result->is_laurent[result->blocks[i].first_exp + j] = 1; } return result; }