Skip to content

Primitive operations

Kevin Lawler edited this page Jun 24, 2013 · 8 revisions

//Older version with modulo, GCC vectors, no macro expansion, for reference
//Modulo is very slow but easily handles differing sizes in {atom, vector} X {atom, vector}, conformable lists
//GCC vectors/SSE/SIMD won't make much difference on plus (von Neumann bottleneck) but may on slower operations
//Note z could be initialized as a or b instead of a new vector under certain conditions

typedef I veci __attribute__ ((vector_size (16)));

K plus(K a, K b) //compare plus() to times() or minus()
{
  I at=a->t, an=a->n, bt=b->t, bn=b->n;
  I type = MAX(ABS(at),ABS(bt));

  P(at <= 0 && bt <= 0 && an != bn,LE)
  P(type > 2,TE)

  //Determine our return values type
  I zt=type;                    //Starting point, worst known type
  if(MIN(at,bt) < 1) zt=-zt;    //Plural?
  if(!at || !bt) zt=0;          //Generic list trumps
  I zn=at>0?bn:an;              //Have to be careful if one is atom and one is [empty?] list
  K z=newK(zt,zn);U(z)          //Finally, we know what we're going to make

  if     (2==ABS(at) && 2==ABS(bt)) DO(zn,kF(z)[i]=kF(a)[i%an]+kF(b)[i%bn])
  else if(2==ABS(at) && 1==ABS(bt)) DO(zn,kF(z)[i]=kF(a)[i%an]+kI(b)[i%bn])
  else if(1==ABS(at) && 2==ABS(bt)) DO(zn,kF(z)[i]=kI(a)[i%an]+kF(b)[i%bn])
  else if(-1==    at  && -1==    bt ) { veci *c=(veci*)a,*d=(veci*)b,*e=(veci*)z; DO(((((zn+3)+1)&~1))/2, e[i]=c[i]+d[i] ) if(z!=b)z->c=1; z->t=zt; z->n=zn; } //demonstration purposes
  else if(1==ABS(at) && 1==ABS(bt)) DO(zn,kI(z)[i]=kI(a)[i%an]+kI(b)[i%bn])
  else if(0==at || 0==bt) dp(&z,plus,a,b);

  R z;
}


//Newer version without modulo, without GCC vectors. Macros are used to simplify replacing modulo.
//Macro expanded: gcc -x c -E - < va.c
K plus(K a, K b)
{
  I at=a->t, an=a->n, bt=b->t, bn=b->n;
  
  I type = (((((at) < 0 ? -(at) : (at))) > (((bt) < 0 ? -(bt) : (bt)))) ? (((at) < 0 ? -(at) : (at))) : (((bt) < 0 ? -(bt) : (bt)))); 
  
  {if(at <= 0 && bt <= 0 && an != bn)return(kerr("length"));}
  {if(type > 2)return(kerr("type"));}
  
  I zt=type; if((((at) < (bt)) ? (at) : (bt)) < 1) zt=-zt; if(!at || !bt) zt=0; I zn=at>0?bn:an;
  K z=newK(zt,zn);{if(!(z))return(0);}

  if (2==((at) < 0 ? -(at) : (at)) && 2==((bt) < 0 ? -(bt) : (bt))) { if (an==bn) { {I i=0,_i=(zn);for(;i<_i;++i){((F*)(((K)z)->k)) [i]= ((((F*)(((K)a)->k)) [i]) + (((F*)(((K)b)->k)) [i]));}} } 
  
  else if (an==1) { {I i=0,_i=(zn);for(;i<_i;++i){((F*)(((K)z)->k)) [i]= ((((F*)(((K)a)->k)) [0]) + (((F*)(((K)b)->k)) [i]));}} } else { {I i=0,_i=(zn);for(;i<_i;++i){((F*)(((K)z)->k)) [i]= ((((F*)(((K)a)->k)) [i]) + (((F*)(((K)b)->k)) [0]));}} } }
  
  else if (2==((at) < 0 ? -(at) : (at)) && 1==((bt) < 0 ? -(bt) : (bt))) { if (an==bn) { {I i=0,_i=(zn);for(;i<_i;++i){((F*)(((K)z)->k)) [i]= ((((F*)(((K)a)->k)) [i]) + (((I*)(((K)b)->k)) [i]));}} }
  
  else if (an==1) { {I i=0,_i=(zn);for(;i<_i;++i){((F*)(((K)z)->k)) [i]= ((((F*)(((K)a)->k)) [0]) + (((I*)(((K)b)->k)) [i]));}} } else { {I i=0,_i=(zn);for(;i<_i;++i){((F*)(((K)z)->k)) [i]= ((((F*)(((K)a)->k)) [i]) + (((I*)(((K)b)->k)) [0]));}} } } 
  
  else if (1==((at) < 0 ? -(at) : (at)) && 2==((bt) < 0 ? -(bt) : (bt))) { if (an==bn) { {I i=0,_i=(zn);for(;i<_i;++i){((F*)(((K)z)->k)) [i]= ((((I*)(((K)a)->k)) [i]) + (((F*)(((K)b)->k)) [i]));}} } else if (an==1) { {I i=0,_i=(zn);for(;i<_i;++i){((F*)(((K)z)->k)) [i]= ((((I*)(((K)a)->k)) [0]) + (((F*)(((K)b)->k)) [i]));}} } else { {I i=0,_i=(zn);for(;i<_i;++i){((F*)(((K)z)->k)) [i]= ((((I*)(((K)a)->k)) [i]) + (((F*)(((K)b)->k)) [0]));}} } } 
  
  else if (1==((at) < 0 ? -(at) : (at)) && 1==((bt) < 0 ? -(bt) : (bt))) { if (an==bn) { {I i=0,_i=(zn);for(;i<_i;++i){((I*)(((K)z)->k)) [i]= ((((I*)(((K)a)->k)) [i]) + (((I*)(((K)b)->k)) [i]));}} } else if (an==1) { {I i=0,_i=(zn);for(;i<_i;++i){((I*)(((K)z)->k)) [i]= ((((I*)(((K)a)->k)) [0]) + (((I*)(((K)b)->k)) [i]));}} } else { {I i=0,_i=(zn);for(;i<_i;++i){((I*)(((K)z)->k)) [i]= ((((I*)(((K)a)->k)) [i]) + (((I*)(((K)b)->k)) [0]));}} } } 
  
  else if (0==at || 0==bt) { dp(&z,plus,a,b); }


  return z;
}


Clone this wiki locally