Exemplo n.º 1
0
static int point_in_poly(double* xcor, double* ycor, long int ncor, double x, double y)
{

  double xv, yv, xnv, ynv;
  int i;
  quadrant_type quad, next_quad, delta, angle;

  /* initialize */
  xv = xcor[0]; yv = ycor[0];

  quad = quadrant(xv,yv, x, y);
  angle = 0;

   /* loop on all vertices of polygon */
  for (i=1; i<ncor; i++) {
    xnv = xcor[i]; ynv = ycor[i];
                /* calculate quadrant and delta from last quadrant */
    next_quad = quadrant(xnv,ynv, x, y);
    delta = next_quad - quad;
    adjust_delta(delta,xv,yv,xnv,ynv,x,y);
    /* add delta to total angle sum */
    angle = angle + delta;
    /* increment for next step */
    quad = next_quad;
    xv = xnv; yv = ynv;
    }
  /* complete 360 degrees (angle of + 4 or -4 ) means inside */
  if ((angle == +4) || (angle == -4)) return 1; else return 0;
}
Exemplo n.º 2
0
void arc_extreme(double x0, double y0, double x1, double y1, double xc, double yc)
			  /* start, end, center */
{
	/* assumes center isn't too far out */
	double r, xmin, ymin, xmax, ymax;
	int j, k;
	x0 -= xc; y0 -= yc;	/* move to center */
	x1 -= xc; y1 -= yc;
	xmin = (x0<x1)?x0:x1; ymin = (y0<y1)?y0:y1;
	xmax = (x0>x1)?x0:x1; ymax = (y0>y1)?y0:y1;
	r = sqrt(x0*x0 + y0*y0);
	if (r > 0.0) {
		j = quadrant(x0,y0);
		k = quadrant(x1,y1);
		if (j == k && y1*x0 < x1*y0) {
			/* viewed as complex numbers, if Im(z1/z0)<0, arc is big */
			if( xmin > -r) xmin = -r; if( ymin > -r) ymin = -r;
			if( xmax <  r) xmax =  r; if( ymax <  r) ymax =  r;
		} else {
			while (j != k) {
				switch (j) {
					case 1: if( ymax <  r) ymax =  r; break; /* north */
					case 2: if( xmin > -r) xmin = -r; break; /* west */
					case 3: if( ymin > -r) ymin = -r; break; /* south */
					case 4: if( xmax <  r) xmax =  r; break; /* east */
				}
				j = j%4 + 1;
			}
		}
	}
	xmin += xc; ymin += yc;
	xmax += xc; ymax += yc;
	extreme(xmin, ymin);
	extreme(xmax, ymax);
}
Exemplo n.º 3
0
int32 Box3f::findQuadrant( float x, float y, float z,
						 int32 n, const MatrixR& MVP )
{
	float c = MVP[0][n]*x + MVP[1][n]*y + MVP[2][n]*z + MVP[3][n] ;
	float w = MVP[0][3]*x + MVP[1][3]*y + MVP[2][3]*z + MVP[3][3] ;
	return quadrant(c, w);
}
Exemplo n.º 4
0
	bool operator <(RationalAngle const &v2) const
	{
		int x1, y1, x2, y2;
		int qa = quadrant(x1, y1), qb = v2.quadrant(x2, y2);
		return qa != qb ? qa < qb
		                : y1*x2 < y2*x1;  // Same as y1/x1 < y2/x2, using real numbers. (And works even with x1 or x2 = 0.)
	}
/*! \fn suppressionKernel(Pgm *pgmMod, Pgm* pgmPhi, double* kernel, int spanX, int spanY, int ic)
 * \brief Return the result of applying non-maximum suppression to a pixel of \a pgmIn1.
 *
 * \param pgmMod Pointer to the Pgm structure containing the modulus component.
 * \param pgmPhi Pointer to the Pgm structure containing the phase component.
 * \param kernel Not used.
 * \param spanX Not used.
 * \param spanY Not used.
 * \param ic The linear index of the central subarray pixel in \a pgmIn1.
 * \return The result the result of non-maximum suppression.
 */
int suppressionKernel(Pgm *pgmMod, Pgm* pgmPhi, double* kernel, int spanX, int spanY, int ic)
{
    int k,l, il;
    int pixels[9];
    int ix = 0;
    
    int width = pgmMod->width;
    
    // Define the left, right, top and bottom span from the
    // center to match the 3x3 pixels matrix
    spanX = 1;
    spanY = 1;
    
    // Copy the image pixels in a local pixels array
    for (k=-spanY, il = ic-width*spanY; k <= spanY; k++, il += width)
        for (l=-spanX; l <= spanX; l++) {
            pixels[ix++] = pgmMod->pixels[il+l];
        }
    
    // Compute the quadrant of the phase of the central image pixel
    int q = quadrant((int)(180.0*pgmPhi->pixels[ic]/127));
    
    // Check if the central pixel is the maximum along the direction
    // perpendicular to the orientation of the gradient
    if((pixels[4] >= pixels[neighbors[2*q]]) && (pixels[4] >= pixels[neighbors[2*q+1]]))
        return pixels[4];
    
    return 0;
}
Exemplo n.º 6
0
/**
* Returns the quadrant of a directed line segment from p0 to p1.
*/
int Quadrant::quadrant(const Coordinate& p0, const Coordinate& p1) {
	double dx=p1.x-p0.x;
	double dy=p1.y-p0.y;
	if (dx==0.0 && dy==0.0)
	{
		throw util::IllegalArgumentException("Cannot compute the quadrant for two identical points " + p0.toString());
	}
	return quadrant(dx, dy);
}
Exemplo n.º 7
0
void Particle::calculateSpin() {
    //calculamos el nuevo vector de orientacion
    _vertex3f nuevo;
    nuevo=_posEnd-_posBegin;
    nuevo.normalize();

    //guardamos el anterior giro
    _spinBegin=normalize(_spinNow);

    //calculamos el giro de destino
    _spinEnd = atan2(nuevo.x,nuevo.z)/M_PI*180.0;
    _spinEnd = this->normalize(_spinEnd);

    //Calculamos el signo del incremento en el giro
    int signo;
    if ( quadrant(_spinBegin) < 3 ) { //alfa en 1º y 2º cuadrante
        if ( _spinEnd < _spinBegin || _spinEnd > normalize(_spinBegin+180) )
            signo = -1;
        else
            signo = 1;
    }else { //alfa en 3º y 4º cuadrante
        if ( _spinEnd > _spinBegin || _spinEnd < _spinBegin-180 )
            signo = 1;
        else
            signo = -1;
    }

    //Calculamos el incremento
    if ( fabs(_spinEnd-_spinBegin) > 180) {
        if ( quadrant(_spinBegin) < 3 ) {
            _incSpin = (fabs((360-_spinEnd)+_spinBegin) / this->_tickTotalSpin) * signo;
        }else {
            _incSpin = (fabs(_spinEnd+(360-_spinBegin)) / this->_tickTotalSpin) * signo;
        }
    }else {
        _incSpin = (fabs(_spinEnd-_spinBegin) / this->_tickTotalSpin) * signo;
    }

    //ticks actuales
    _tick = 0;

}
Exemplo n.º 8
0
static void arc_extreme(double x0, double y0, double x1, double y1, double xc, double yc)
		/* start, end, center */
{		/* assumes center isn't too far out */
	double r;
	int j, k;
	printf("#start %g,%g, end %g,%g, ctr %g,%g\n", x0,y0, x1,y1, xc,yc);
	y0 = -y0; y1 = -y1; yc = -yc;	// troff's up is eric's down
	x0 -= xc; y0 -= yc;	/* move to center */
	x1 -= xc; y1 -= yc;
	xmin = (x0<x1)?x0:x1; ymin = (y0<y1)?y0:y1;
	xmax = (x0>x1)?x0:x1; ymax = (y0>y1)?y0:y1;
	r = sqrt(x0*x0 + y0*y0);
	if (r > 0.0) {
		j = quadrant(x0,y0);
		k = quadrant(x1,y1);
		if (j == k && y1*x0 < x1*y0) {
			/* viewed as complex numbers, if Im(z1/z0)<0, arc is big */
			if( xmin > -r)
				xmin = -r;
			if( ymin > -r)
				ymin = -r;
			if( xmax <  r)
				xmax =  r;
			if( ymax <  r)
				ymax =  r;
		} else {
			while (j != k) {
				switch (j) {
				case 1: if( ymax <  r) ymax =  r; break; /* north */
				case 2: if( xmin > -r) xmin = -r; break; /* west */
				case 3: if( ymin > -r) ymin = -r; break; /* south */
				case 4: if( xmax <  r) xmax =  r; break; /* east */
				}
				j = j%4 + 1;
			}
		}
	}
	xmin += xc; ymin += yc; ymin = -ymin;
	xmax += xc; ymax += yc; ymax = -ymax;
}
Exemplo n.º 9
0
Arquivo: frame.c Projeto: dgl/wmii
static bool
bdown_event(Window *w, void *aux, XButtonEvent *e) {
	Frame *f;
	Client *c;

	c = aux;
	f = c->sel;

	if((e->state & def.mod) == def.mod) {
		switch(e->button) {
		case Button1:
			focus(c, false);
			mouse_resize(c, Center, true);
			break;
		case Button2:
			frame_restack(f, nil);
			view_restack(f->view);
			focus(c, false);
			grabpointer(c->framewin, nil, cursor[CurNone], ButtonReleaseMask);
			break;
		case Button3:
			focus(c, false);
			mouse_resize(c, quadrant(f->r, Pt(e->x_root, e->y_root)), true);
			break;
		default:
			XAllowEvents(display, ReplayPointer, e->time);
			break;
		}
	}else {
		if(e->button == Button1) {
			if(!e->subwindow) {
				frame_restack(f, nil);
				view_restack(f->view);
				mouse_checkresize(f, Pt(e->x, e->y), true);
			}

			if(f->client != selclient())
				focus(c, false);
		}
		if(e->subwindow)
			XAllowEvents(display, ReplayPointer, e->time);
		else {
			/* Ungrab so a menu can receive events before the button is released */
			XUngrabPointer(display, e->time);
			sync();

			event("ClientMouseDown %#C %d\n", f->client, e->button);
		}
	}
	return false;
}
Exemplo n.º 10
0
/**
 * Assumes that @mask represents a network mask and returns its prefix length.
 */
static __u8 dot_decimal_to_cidr(struct in6_addr *mask)
{
	__u32 quad;
	unsigned int i;
	unsigned int j;

	for (i = 0; i < 4; i++) {
		quad = quadrant(mask, i);
		if (quad == 0)
			return 32 * i;
		if (quad != 0xFFFFFFFFu) {
			for (j = 0; last_bit_is_zero(quad); j++)
				quad >>= 1;
			return 32 * (i + 1) - j;
		}
	}

	return 128;
}
Exemplo n.º 11
0
int findBestQuadrant(TH1D *ahisto) {
  
  Int_t quadrant(0);
  Float_t qarea(0.0);
  Float_t qqarea[4];
  Float_t max_x(0.0), min_x(0.0), tot_x(0.0);
  Float_t sfactor(0.0);
  Int_t max_bin(0), sep_bin(0), k;
  
  Float_t value = 0;
  Float_t maxvalue =0;
  Float_t maximum = ahisto->GetMaximum();

  max_x=(ahisto->GetXaxis())->GetXmax();
  min_x=(ahisto->GetXaxis())->GetXmin();
  tot_x= max_x - min_x;
  
  qarea=(tot_x*maximum)/4;
  
  max_bin=ahisto->GetNbinsX();
  sep_bin=max_bin/4;

  sfactor=tot_x/max_bin;

  qqarea[0]=qarea-sfactor*(ahisto->Integral(1,sep_bin));
  qqarea[1]=qarea-sfactor*(ahisto->Integral(sep_bin+1,2*sep_bin));
  qqarea[2]=qarea-sfactor*(ahisto->Integral(2*sep_bin+1,3*sep_bin));
  qqarea[3]=qarea-sfactor*(ahisto->Integral(3*sep_bin+1,max_bin));
  
  //printf("%d Areas: %f %f %f %f \n",i, qqarea[0],qqarea[1],qqarea[2],qqarea[3]);
  
  for(k=0; k<4 ; k++) {
    value=qqarea[k];
    if(value > maxvalue) {
      maxvalue = value;
      quadrant=k;
    }
  }
  
  return quadrant;
  
}
Exemplo n.º 12
0
QgsCircularString *QgsCircle::toCircularString( bool oriented ) const
{
  std::unique_ptr<QgsCircularString> circString( new QgsCircularString() );
  QgsPointSequence points;
  QVector<QgsPoint> quad;
  if ( oriented )
  {
    quad = quadrant();
  }
  else
  {
    quad = northQuadrant();
  }
  quad.append( quad.at( 0 ) );
  for ( QVector<QgsPoint>::const_iterator it = quad.constBegin(); it != quad.constEnd(); ++it )
  {
    points.append( *it );
  }
  circString->setPoints( points );

  return circString.release();
}
Exemplo n.º 13
0
void
arc_extreme(obj *p) {
    /* assumes center isn't too far out */

    double	x0, y0, x1, y1, xc, yc;  /* start, end, center */
    double	r, xmin, ymin, xmax, ymax, wgt;
    int	j, k;

    x0 = p->o_val[N_VAL+2].f - (xc = p->o_x);    /* translate to center */
    y0 = p->o_val[N_VAL+3].f - (yc = p->o_y);
    x1 = p->o_val[N_VAL+4].f - xc;
    y1 = p->o_val[N_VAL+5].f - yc;
    xmin = (x0<x1)?x0:x1;
    ymin = (y0<y1)?y0:y1;
    xmax = (x0>x1)?x0:x1;
    ymax = (y0>y1)?y0:y1;
    r = p->o_val[N_VAL].f;
    if (r > 0.0) {
        j = quadrant(x0,y0);
        k = quadrant(x1,y1);
        if (j == k && y1*x0 <= x1*y0) {
            /* viewed as complex numbers, if Im(z1/z0)<0, arc is big */
            if( xmin > -r)
                xmin = -r;
            if( ymin > -r)
                ymin = -r;
            if( xmax <  r)
                xmax =  r;
            if( ymax <  r)
                ymax =  r;
        } else {
            while (j != k) {
                switch (j) {
                case 1:
                    if( ymax <  r) ymax =  r;
                    break; /* north */
                case 2:
                    if( xmin > -r) xmin = -r;
                    break; /* west */
                case 3:
                    if( ymin > -r) ymin = -r;
                    break; /* south */
                case 4:
                    if( xmax <  r) xmax =  r;
                    break; /* east */
                }
                j = j%4 + 1;
            }
        }
    }
    if (p->o_type == SECTOR) {	/* include center */
        if (xmin * xmax > 0) {
            if (xmin > 0) xmin = 0;
            else xmax = 0;
        }
        if (ymin * ymax > 0) {
            if (ymin > 0) ymin = 0;
            else ymax = 0;
        }
    }
    p->o_wid = xmax - xmin;
    p->o_ht  = ymax - ymin;
    p->o_val[N_VAL+6].f = -0.5 * (xmin+xmax);  /* record offset to center */
    p->o_val[N_VAL+7].f = -0.5 * (ymin+ymax);
    wgt = p->o_weight/2;
    track_bounds(xmin+xc-wgt, ymin+yc-wgt, xmax+xc+wgt, ymax+yc+wgt);
}
Exemplo n.º 14
0
/**
 * @brief View-volume culling
 * 
 * View-volume culling: axis-aligned bounding box against view volume,
 * given as Model/View/Projection matrix.
 * Inputs:
 *    MVP:       Matrix from object to NDC space
 *                 (model/view/projection)
 * Inputs/Outputs:
 *    cullBits:  Keeps track of which planes we need to test against.
 *               Has three bits, for X, Y and Z.  If cullBits is 0,
 *               then the bounding box is completely inside the view
 *               and no further cull tests need be done for things
 *               inside the bounding box.  Zero bits in cullBits mean
 *               the bounding box is completely between the
 *               left/right, top/bottom, or near/far clipping planes.
 * Outputs:
 *    bool:    TRUE if bbox is completely outside view volume
 *               defined by MVP.
 *
 *
 *
 * How:
 *
 * An axis-aligned bounding box is the set of all points P,
 * Pmin < P < Pmax.  We're interested in finding out whether or not
 * any of those points P are clipped after being transformed through
 * MVP (transformed into clip space).
 *
 * A transformed point P'[x,y,z,w] is inside the view if [x,y,z] are
 * all between -w and w.  Otherwise the point is outside the view.
 *
 * Instead of testing individual points, we want to treat the range of
 * points P.  We want to know if:  All points P are clipped (in which
 * case the cull test succeeds), all points P are NOT clipped (in
 * which case they are completely inside the view volume and no more
 * cull tests need be done for objects inside P), or some points are
 * clipped and some aren't.
 *
 * P transformed into clip space is a 4-dimensional solid, P'.  To
 * speed things up, this algorithm finds the 4-dimensional,
 * axis-aligned bounding box of that solid and figures out whether or
 * not that bounding box intersects any of the sides of the view
 * volume.  In the 4D space with axes x,y,z,w, the view volume planes
 * are the planes x=w, x=-w, y=w, y=-w, z=w, z=-w.
 *
 * This is all easier to think about if we think about each of the X,
 * Y, Z axes in clip space independently; worrying only about the X
 * axis for a moment:
 *
 * The idea is to find the minimum and maximum possible X,W
 * coordinates of P'.  If all of the points in the
 * [(Xmin,Xmax),(Wmin,Wmax)] range satisfy -|W| < X < |W| (|W| is
 * absolute value of W), then the original bounding box P is
 * completely inside the X-axis (left/right) clipping planes of the
 * view volume.  In (x,w) space, a point (x,w) is clipped depending on
 * which quadrant it is in:
 *
 *    x=-w       x=w
 *      \   Q0   /
 *       \  IN  /
 *        \    /
 *         \  /
 * Q1       \/  Q2
 * CLIPPED  /\  CLIPPED    
 *         /  \ 
 *        /    \ 
 *       /  Q3  \ 
 *      / CLIPPED\ 
 *
 * If the axis-aligned box [(Xmin,Xmax),(Wmin,Wmax)] lies entirely in
 * Q0, then it is entirely inside the X-axis clipping planes (IN
 * case).  If it is not in Q0 at all, then it is clipped (OUT).  If it
 * straddles Q0 and some other quadrant, the bounding box intersects
 * the clipping planes (STRADDLE).  The 4 corners of the bounding box
 * are tested first using bitwise tests on their quadrant numbers; if
 * they determine the case is STRADDLE then a more refined test is
 * done on the 8 points of the original bounding box.
 * The test isn't perfect-- a bounding box that straddles both Q1 and
 * Q2 may be incorrectly classified as STRADDLE; however, those cases
 * are rare and the cases that are incorrectly classified will likely
 * be culled when testing against the other clipping planes (these
 * cases are cases where the bounding box is near the eye).
 * 
 * Finding [(Xmin,Xmax),(Wmin,Wmax)] is easy.  Consider Xmin.  It is
 * the smallest X coordinate when all of the points in the range
 * Pmin,Pmax are transformed by MVP; written out:
 *     X = P[0]*M[0][0] + P[1]*M[1][0] + P[2]*M[2][0] + M[3][0]
 * X will be minimized when each of the terms is minimized.  If the
 * matrix entry for the term is positive, then the term is minimized
 * by choosing Pmin; if the matrix entry is negative, the term is
 * minimized by choosing Pmax.  Three 'if' test will let us calculate
 * the transformed Xmin.  Xmax can be calculated similarly.
 * 
 * Testing for IN/OUT/STRADDLE for the Y and Z coordinates is done
 * exactly the same way.
 */
bool Box3f::outside(const MatrixR& MVP, int32& cullBits) const
{
	float Wmax = minExtreme(m_max, m_min, MVP, 3);
	if (Wmax < 0) return true;

	float Wmin = minExtreme(m_min, m_max, MVP, 3);

	// Do each coordinate:
	for (int32 i = 0; i < 3; i++) 
	{
		if (cullBits & (1<<i))
		{  // STRADDLES:
			float Cmin = minExtreme(m_min, m_max, MVP, i);
			
			// The and_bits and or_bits are used to keep track of
			// which quadrants point lie in.  The cases are:
			//
			// All in Q0:  IN
			//    (or_bits == 0)  --> and_bits MUST also be 0
			// Some/all in Q1, some/all in Q3: CULLED
			// Some/all in Q2, some/none in Q3: CULLED
			//    (and_bits != 0, or_bits != 0)
			// Some in Q1, some in Q2, some/none in Q3: STRADDLE
			//    (and_bits == 0, or_bits !=0)
			//
			int32 and_bits;
			int32 or_bits;
			and_bits = or_bits = quadrant(Cmin, Wmin);

			int32 q0 = quadrant(Cmin, Wmax);
			and_bits &= q0;
			or_bits |= q0;
			// Hit the STRADDLE case as soon as and_bits == 0 and
			// or_bits != 0:
			if (!(and_bits == 0 && or_bits != 0)) 
			{
				float Cmax = minExtreme(m_max, m_min, MVP, i);
				
				q0 = quadrant(Cmax, Wmin);
				and_bits &= q0;
				or_bits |= q0;
				
				if (!(and_bits == 0 && or_bits != 0)) 
				{
					q0 = quadrant(Cmax, Wmax);
					and_bits &= q0;
					or_bits |= q0;
					
					// Either completely IN or completely OUT:
					if (or_bits == 0) 
					{ // IN
						cullBits &= ~(1<<i); // Clear bit
						continue; // Continue for loop
					}
					else if (and_bits != 0) 
					{
						return true;  // CULLED
					}
				}
			}

			// Before we give up and just claim it straddles, do a
			// more refined test-- check the 8 corners of the
			// bounding box:
			
			// Test to see if all 8 corner points of the bounding box
			// are in the same quadrant.  If so, the object is either
			// completely in or out of the view.  Otherwise, it straddles
			// at least one of the view boundaries.
			and_bits = or_bits = findQuadrant(m_min[0], m_min[1], m_min[2], i, MVP);
			if (and_bits == 0 && or_bits != 0) continue;
			
			q0 = findQuadrant(m_max[0], m_max[1], m_max[2], i, MVP);
			and_bits &= q0;
			or_bits |= q0;
			if (and_bits == 0 && or_bits != 0) continue;

			q0 = findQuadrant(m_max[0], m_min[1], m_min[2], i, MVP);
			and_bits &= q0;
			or_bits |= q0;
			if (and_bits == 0 && or_bits != 0) continue;

			q0 = findQuadrant(m_min[0], m_max[1], m_max[2], i, MVP);
			and_bits &= q0;
			or_bits |= q0;
			if (and_bits == 0 && or_bits != 0) continue;
			
			q0 = findQuadrant(m_min[0], m_max[1], m_min[2], i, MVP);
			and_bits &= q0;
			or_bits |= q0;
			if (and_bits == 0 && or_bits != 0) continue;

			q0 = findQuadrant(m_max[0], m_min[1], m_max[2], i, MVP);
			and_bits &= q0;
			or_bits |= q0;
			if (and_bits == 0 && or_bits != 0) continue;
			
			q0 = findQuadrant(m_max[0], m_max[1], m_min[2], i, MVP);
			and_bits &= q0;
			or_bits |= q0;
			if (and_bits == 0 && or_bits != 0) continue;

			q0 = findQuadrant(m_min[0], m_min[1], m_max[2], i, MVP);
			and_bits &= q0;
			or_bits |= q0;

			// Either completely IN or completely OUT:
			if (or_bits == 0) 
			{ // IN
				cullBits &= ~(1<<i); // Clear bit
				continue; // Continue for loop
			}
			else if (and_bits != 0) 
			{
				return true;  // CULLED
			}
		}
	}
	return false;// Not culled
}
Exemplo n.º 15
0
RcppExport SEXP bbivDPM(SEXP arg1, SEXP arg2, SEXP arg3) {
  // 3 arguments
  // arg1 for parameters
  // arg2 for data
  // arg3 for Gibbs

  // data
  List list2(arg2); 

  const MatrixXd X=as< Map<MatrixXd> >(list2["X"]),
    Z=as< Map<MatrixXd> >(list2["Z"]);

  const VectorXi v1=as< Map<VectorXi> >(list2["tbin"]),
    v2=as< Map<VectorXi> >(list2["ybin"]);

  const int N=X.rows(), p=X.cols(), q=Z.cols(), r=p+q, s=p+r;

#ifdef DEBUG_NEAL8
  List P, Phi, B;
  VectorXi S, one;
  one.setConstant(N, 1);
#endif

  // parameters
  List list1(arg1), 
    beta_info=list1["beta"], 
    rho_info=list1["rho"], 
    mu_info=list1["mu"], 
    theta_info=list1["theta"],
    dpm_info=list1["dpm"], // DPM
    alpha_info=dpm_info["alpha"], // alpha random
    alpha_prior; // alpha random

  const int m=as<int>(dpm_info["m"]); // DPM
  //  const double alpha=as<double>(dpm_info["alpha"]); // DPM
  const int alpha_fixed=as<int>(alpha_info["fixed"]); // alpha random
  double alpha=as<double>(alpha_info["init"]); // alpha random

  if(alpha_fixed==0) alpha_prior=alpha_info["prior"]; // alpha random

  VectorXi C=as< Map<VectorXi> >(dpm_info["C"]), 
    states=as< Map<VectorXi> >(dpm_info["states"]);
  
  /* checks done in neal8
  if(states.sum()!=N || C.size()!=N) { // limited reality check of C and states
    C.setConstant(N, 0); 
    states.setConstant(1, N); 
  }
  */

  // prior parameters
  List beta_prior=beta_info["prior"],
    // no prior parameters for rho
    dpm_prior=dpm_info["prior"],
    theta_prior=theta_info["prior"];

  const double beta_prior_mean=as<double>(beta_prior["mean"]);
  const double beta_prior_prec=as<double>(beta_prior["prec"]);

  const VectorXd theta_prior_mean=as< Map<VectorXd> >(theta_prior["mean"]);
  const MatrixXd theta_prior_prec=as< Map<MatrixXd> >(theta_prior["prec"]);

  // initialize parameters
  double beta    =as<double>(beta_info["init"]); 
  double rho_init=as<double>(rho_info["init"]);  // DPM
  //int    rho_MH  =as<int>(rho_info["MH"]);

  Vector2d mu_init=as< Map<VectorXd> >(mu_info["init"]); // DPM
  VectorXd theta  =as< Map<VectorXd> >(theta_info["init"]);
  VectorXd rho(N);  // DPM

  /*
  VectorXi C, states; // DPM
  C.setConstant(N, 0); // DPM
  states.setConstant(1, N); // DPM
  */

  MatrixXd mu(N, 2), phi(1, 3); // DPM
  phi(0, 0)=mu_init[0]; // DPM
  phi(0, 1)=mu_init[1]; // DPM
  phi(0, 2)=rho_init; // DPM

  // Gibbs
  List list3(arg3);

  const int burnin=as<int>(list3["burnin"]), M=as<int>(list3["M"]), 
    thin=as<int>(list3["thin"]);

  VectorXi quadrant(N);

  VectorXd t(N), y(N); // latents

  // prior parameter intermediate values
  double beta_prior_prod=beta_prior_prec * beta_prior_mean;

  VectorXd theta_prior_prod=theta_prior_prec * theta_prior_mean;

  Matrix2d Sigma, Tprec, B_inverse;

  B_inverse.setIdentity();

  VectorXd gamma=theta.segment(0, p), 
    delta=theta.segment(p, q), 
    eta  =theta.segment(r, p);

  MatrixXd eps(N, 2), D(N, 2), theta_cond_var_root(s, s), W(2, s), A(N, r+4); // DPM semi

  W.setZero();

  MatrixXd theta_cond_prec(s, s);

  VectorXd theta_cond_prod(s), w(r), mu_t(N), mu_y(N), sd_y(N);

  Vector2d u, R, mu_u; // DPM

  double beta_prec, beta_prod, beta_cond_var, beta_cond_mean, beta2; // DPM

  int h=0, i, l; 

  List GS(M); //DPM

  // assign quadrants
  for(i=0; i<N; ++i) {
    if(v1[i]==0 && v2[i]==0) quadrant[i] = 3;
    else if(v1[i]==0 && v2[i]==1) quadrant[i] = 2;
    else if(v1[i]==1 && v2[i]==0) quadrant[i] = 4;
    else if(v1[i]==1 && v2[i]==1) quadrant[i] = 1;
  }

  // Gibbs loop
  //for(int l=-burnin; l<=(M-1)*thin; ++l) {

  l=-burnin;

  do{
    // populate mu/rho //DPM
    for(i=0; i<N; ++i) {
      mu(i, 0)=phi(C[i], 0);
      mu(i, 1)=phi(C[i], 1);
      rho[i]=phi(C[i], 2);

      mu_t[i]=mu(i, 0);
      mu_y[i]=mu(i, 1);
    }

    // generate latents
    // mu_t = mu.col(0); //DPM
    mu_t += (Z*delta + X*gamma);

    // mu_y = mu.col(1); //DPM
    mu_y += (beta*mu_t + X*eta);

    beta2=pow(beta, 2.);

    for(i=0; i<N; ++i) {
      sd_y[i] = sqrt(beta2+2.*beta*rho[i]+1.); //DPM

      mu_u[0]=mu_t[i];
      mu_u[1]=mu_y[i]/sd_y[i]; //DPM
      //             z,    quadrant,    rho,                   burnin 
      u=rbvtruncnorm(mu_u, quadrant[i], (beta+rho[i])/sd_y[i], 10);
  
      t[i]=u[0];
      y[i]=sd_y[i]*u[1];
    }

    // sample beta
    D.col(0) = (t - mu.col(0) - X*gamma - Z*delta); //DPM
    D.col(1) = (y - mu.col(1) - X*eta); //DPM

    beta_prec=0.;
    beta_prod=0.;

    for(i=0; i<N; ++i) {
      double Sigma_det=1.-pow(rho[i], 2.); //DPM

      beta_prec += pow(t[i], 2.)/Sigma_det; //DPM
      beta_prod += -t[i]*(rho[i]*D(i, 0)-D(i, 1))/Sigma_det; //DPM
    }

    beta_cond_var=1./(beta_prec+beta_prior_prec);

    beta_cond_mean=beta_cond_var*(beta_prod+beta_prior_prod);

    beta=rnorm1d(beta_cond_mean, sqrt(beta_cond_var));

    B_inverse(1, 0)=-beta;

    // sample theta
    theta_cond_prec=theta_prior_prec;
    theta_cond_prod=theta_prior_prod;

    for(i=0; i<N; ++i) {
      double Sigma_det=1.-pow(rho[i], 2.); //DPM

      Tprec(0, 0)=1./Sigma_det;      Tprec(0, 1)=-rho[i]/Sigma_det; //DPM
      Tprec(1, 0)=-rho[i]/Sigma_det; Tprec(1, 1)=1./Sigma_det; //DPM

      mu_u[0]=mu(i, 0);  //DPM
      mu_u[1]=mu(i, 1);  //DPM

      W.block(0, 0, 1, p)=X.row(i);
      W.block(0, p, 1, q)=Z.row(i);
      W.block(1, r, 1, p)=X.row(i);

      theta_cond_prec += (W.transpose() * Tprec * W);

      u[0]=t[i];
      u[1]=y[i];

      R=B_inverse*u-mu_u; //DPM

      theta_cond_prod += (W.transpose() * Tprec * R);
    }

    theta_cond_var_root=inv_root_chol(theta_cond_prec);

    theta=theta_cond_var_root*(rnormXd(s)+theta_cond_var_root.transpose()*theta_cond_prod);

    gamma=theta.segment(0, p); 
    delta=theta.segment(p, q); 
    eta  =theta.segment(r, p);

    // sample mu and rho
    // this for block should be placed in P0
    // however, to keep changes minimal, we keep it here
    for(i=0; i<N; ++i) {

      W.block(0, 0, 1, p)=X.row(i);
      W.block(0, p, 1, q)=Z.row(i);
      W.block(1, r, 1, p)=X.row(i);

      u[0]=t[i];
      u[1]=y[i];

      eps.row(i) = (B_inverse*u - W*theta).transpose(); //DPM
    }

    /* semi block begins */
    A.block(0, 0, N, 2)=eps;
    A.col(2)=t;
    A.col(3)=y;
    A.block(0, 4, N, p)=X;
    A.block(0, p+4, N, q)=Z;

    List psi=List::create(Named("mu0")=as< Map<VectorXd> >(dpm_prior["mu0"]), 
			  Named("T0")=as< Map<MatrixXd> >(dpm_prior["T0"]),   
			  Named("S0")=as< Map<MatrixXd> >(dpm_prior["S0"]),  
			  Named("beta")=beta,   
			  Named("gamma")=gamma, 
			  Named("delta")=delta, 
			  Named("eta")=eta);   

    if(alpha_fixed==0) 
      alpha=bbiv_alpha(states.size(), N, alpha, alpha_prior); // alpha random

    List dpm_step=neal8(A, C, phi, states, m, alpha, psi, 
     			&bbivF, &bbivG0, &bbivP0);
    /* semi block end */

    /*
    C=as< Map<VectorXi> >(dpm_step[0]);
    phi=as< Map<MatrixXd> >(dpm_step[1]);
    states=as< Map<VectorXi> >(dpm_step[2]);
    */

    C=as< Map<VectorXi> >(dpm_step["C"]);
    phi=as< Map<MatrixXd> >(dpm_step["phi"]);
    states=as< Map<VectorXi> >(dpm_step["states"]);

#ifdef DEBUG_NEAL8
    S=as< Map<VectorXi> >(dpm_step["S"]);
    P=dpm_step["P"]; 
    Phi=dpm_step["Phi"];
    B=dpm_step["B"]; 
#endif
    
    if(l>=0 && l%thin == 0) {
      h = (l/thin);

#ifdef DEBUG_NEAL8
      GS[h]=List::create(Named("beta")=beta, Named("theta")=theta,
			 Named("C")=C+one, Named("phi")=phi, 
			 Named("states")=states, Named("alpha")=alpha, 
			 Named("S")=S+one, Named("P")=P, 
			 Named("Phi")=Phi, Named("B")=B);
#else
      if(alpha_fixed==0) // alpha random
	GS[h]=List::create(Named("beta")=beta, Named("theta")=theta, 
			   Named("C")=C, Named("phi")=phi, 
			   Named("states")=states, Named("alpha")=alpha);
      else GS[h]=List::create(Named("beta")=beta, Named("theta")=theta, 
                       Named("C")=C, Named("phi")=phi, Named("states")=states);
#endif

      // GS[h]=List::create(Named("beta")=beta, Named("theta")=theta, 
      //  			 Named("C")=C, Named("phi")=phi, Named("states")=states,
      // 			 Named("m")=m, Named("alpha")=alpha, Named("psi")=psi);
    }

    l++;

  } while (l<=(M-1)*thin); 

  return wrap(GS);
}