Esempio n. 1
0
	NDARRAY3_LOOP_OVER_START( n, i, j, k) {
		ndarray3_set( n, i,j,k,  sqrt(
				  SQUARED( i - (n->sz[0]-1)/2.0 )
				+ SQUARED( j - (n->sz[1]-1)/2.0 )
				+ SQUARED( k - (n->sz[2]-1)/2.0 )
				) );
	} NDARRAY3_LOOP_OVER_END;
D3DVECTOR* VecNormalize(D3DVECTOR *pOut, const D3DVECTOR *pV1)
{
    FLOAT norm_sq = SQUARED(pV1->x) + SQUARED(pV1->y) + SQUARED(pV1->z);

    if (norm_sq > FLT_MIN)
    {
        FLOAT f = sqrtf(norm_sq);
        pOut->x = pV1->x / f;
        pOut->y = pV1->y / f;
        pOut->z = pV1->z / f;
    }
    else
    {
        pOut->x = 0.0f;
        pOut->y = 0.0f;
        pOut->z = 0.0f;
    }
    return pOut;
}
Esempio n. 3
0
int main(int argc, char *argv[]) {

    // Paso por parametro del valor de M
    if(argc > 1){
	M = atoi(argv[1]);
	//printf("Running with M = %d\n", M);
    }
    else{
	//printf("Running with default M = 10000\n");
    }



    // Los vectores en C++ son escencialmente arreglos en C con una interfaz
    // más conveniente. Donde sea que se pueda usar arreglos, se puede usar
    // vectores. Cuando se necesita la dirección de memoria de un arreglo, hay
    // que usar la dirección del primer elemento del vector: &x[0].  x por sí
    // solo no sirve ya que es un objeto que encapsula al verdadero arreglo.

    std::vector<float> x1;
    x1.reserve(N);
    x1.resize(N);

    // copiar datos del archivo de entrada al vector
    std::ifstream input_file(data_file_name, std::ios::binary | std::ios::in);
    if (!input_file) {
        std::cerr << "No se pudo abrir el archivo " << data_file_name << std::endl;
        std::exit(-1);
    }
    input_file.read((char *) &x1[0], N * sizeof(float));
    input_file.close();

    // crear una copia del vector, de modo de tener
    // uno para mapear en la GPU y otro en la CPU
    std::vector<float> x2(x1);
    // mapear x1 en la CPU y x2 en la GPU
    cpu_map(x1, M);
    gpu_map(&x2[0], x2.size(), M);

    // verificar que los resultados son prácticamente iguales
    float squared_diff_norm = 0.0;
#   define SQUARED(x) ((x) * (x))
#   pragma omp parallel reduction(+: squared_diff_norm)
    for (unsigned i = 0; i < N; ++i)
        squared_diff_norm += SQUARED(x1[i] - x2[i]);
	// Comentar para tests
    //std::cout << "Norma de la diferencia: " << std::sqrt(squared_diff_norm) << std::endl;

	// Descomentar para tests
    std::cout << std::sqrt(squared_diff_norm) << std::endl;
}
Esempio n. 4
0
ndarray3* orion_Makefilter(
		size_t nx, size_t ny, size_t nz,
		int hdaf_approx_degree,
		float scale_factor,
		orion_Makefilter_flag flag) {
	size_t n[] = { nx, ny, nz };
	const size_t ndims = sizeof( n ) / sizeof( size_t ); /* 3 dimensions */

	float kmin[ndims];
	float kmax[ndims];
	float dk[ndims];
	size_t k_axis_sz[ndims];
	float64* k_axis[ndims];

	for( int dim_idx = 0; dim_idx < ndims; dim_idx++ ) {
		kmin[dim_idx] = 0;
		kmax[dim_idx] = M_PI;

		dk[dim_idx] = 2*M_PI / n[dim_idx];

		/* kmin(:) : dk(:) : kmax(:) */
		k_axis[dim_idx] =
			matlab_colonop_float64(kmin[dim_idx], dk[dim_idx], kmax[dim_idx], &k_axis_sz[dim_idx]);
	}

	ndarray3* Kxyz = ndarray3_new(
			k_axis_sz[0],
			k_axis_sz[1],
			k_axis_sz[2] );

	NDARRAY3_LOOP_OVER_START( Kxyz, i0, i1, i2) {
		/* kx .^ 2 + ky .^ 2 + kz .^ 2 */
		ndarray3_set(Kxyz, i0, i1, i2,
				  SQUARED(k_axis[0][i0])
				+ SQUARED(k_axis[1][i1])
				+ SQUARED(k_axis[2][i2]) );
	} NDARRAY3_LOOP_OVER_END;
void TapGestureRecognizer::onTouchBegan(const Touch *touch)
{
    if (numTouches() > numTouchesRequired()) {
        if (state() == State::Possible) {
            setState(State::Failed);
        } else {
            ignoreTouch(touch);
        }
        return;
    }

    if (numTouches() == 1) {
        m_timer->start(maxTapDuration());
    }

    if (numTapsRequired() > 1) {
        if (m_tapCounter == 0) {
            Point p;
            p.x = touch->computedX();
            p.y = touch->computedY();
            m_initialTouchPoints.append(p);
        } else {
            bool found = false;
            float deltaX = 0.0f;
            float deltaY = 0.0f;
            foreach (const Point& p, m_initialTouchPoints) {
                deltaX = p.x - touch->computedX();
                deltaY = p.y - touch->computedY();
                if (SQUARED_PYTHAGOREAN(deltaY, deltaX) <=
                    SQUARED(maxTapDistance())) {
                    found = true;
                    break;
                }
            }

            if (!found) {
                setState(State::Failed);
                return;
            }
        }
    }
Esempio n. 6
0
float cart_distance(struct point pt1, struct point pt2){
  return sqrt(SQUARED(pt1.x-pt2.x) + SQUARED(pt1.y-pt2.y) 
	      + SQUARED(pt1.z-pt2.z));
}
Esempio n. 7
0
INTERNAL u32 moveEntity(GameWorldState *world, MemoryArena_ *transientArena,
                        Entity *entity, i32 entityIndex, v2 ddP, f32 dt,
                        f32 ddPSpeed)
{
	ASSERT(ABS(ddP.x) <= 1.0f && ABS(ddP.y) <= 1.0f);
	/*
	    Assuming acceleration A over t time, then integrate twice to get

	    newVelocity = a*t + oldVelocity
	    newPos = (a*t^2)/2 + oldVelocity*t + oldPos
	*/

	if (ddP.x > 0.0f && ddP.y > 0.0f)
	{
		// NOTE(doyle): Cheese it and pre-compute the vector for
		// diagonal using pythagoras theorem on a unit triangle 1^2
		// + 1^2 = c^2
		ddP = v2_scale(ddP, 0.70710678118f);
	}

	ddP           = v2_scale(ddP, world->pixelsPerMeter * ddPSpeed);
	v2 oldDp      = entity->dP;
	v2 resistance = v2_scale(oldDp, 2.0f);
	ddP           = v2_sub(ddP, resistance);

	v2 newDp = v2_add(v2_scale(ddP, dt), oldDp);

	v2 ddPHalf          = v2_scale(ddP, 0.5f);
	v2 ddPHalfDtSquared = v2_scale(ddPHalf, (SQUARED(dt)));
	v2 oldDpDt          = v2_scale(oldDp, dt);
	v2 oldPos           = entity->pos;

	v2 newPos = v2_add(v2_add(ddPHalfDtSquared, oldDpDt), oldPos);

	i32 collisionIndex = -1;
	// TODO(doyle): Collision for rects, (need to create vertex list for it)
	for (i32 i = 1; i < world->entityIndex; i++)
	{
		if (i == entityIndex) continue;

		Entity *checkEntity = &world->entityList[i];
		ASSERT(checkEntity->id != entity->id);

		if (world->collisionTable[entity->type][checkEntity->type])
		{
			ASSERT(entity->vertexPoints);
			ASSERT(checkEntity->vertexPoints);

			/* Create entity edge lists */
			v2 *entityVertexListOffsetToP =
			    entity_generateUpdatedVertexList(transientArena, entity);

			v2 *checkEntityVertexListOffsetToP =
			    entity_generateUpdatedVertexList(transientArena, checkEntity);

			v2 *entityEdgeList =
			    createNormalEdgeList(transientArena, entityVertexListOffsetToP,
			                         entity->numVertexPoints);

			v2 *checkEntityEdgeList = createNormalEdgeList(
			    transientArena, checkEntityVertexListOffsetToP,
			    checkEntity->numVertexPoints);

			/* Combine both edge lists into one */
			i32 totalNumEdges =
			    checkEntity->numVertexPoints + entity->numVertexPoints;
			v2 *edgeList =
			    memory_pushBytes(transientArena, totalNumEdges * sizeof(v2));
			for (i32 i = 0; i < entity->numVertexPoints; i++)
			{
				edgeList[i] = entityEdgeList[i];
			}

			for (i32 i = 0; i < checkEntity->numVertexPoints; i++)
			{
				edgeList[i + entity->numVertexPoints] = checkEntityEdgeList[i];
			}

			if (checkEdgeProjectionOverlap(
			        entityVertexListOffsetToP, entity->numVertexPoints,
			        checkEntityVertexListOffsetToP,
			        checkEntity->numVertexPoints, edgeList, totalNumEdges))
			{
				collisionIndex = i;
			}
		}

		if (collisionIndex != -1) break;
	}

	entity->dP  = newDp;
	entity->pos = newPos;

	return collisionIndex;
}
Esempio n. 8
0
void bz_comp(
	int npoints,				/* INPUT: # of points */
	int xcol[     MAX_BOZORTH_MINUTIAE ],	/* INPUT: x cordinates */
	int ycol[     MAX_BOZORTH_MINUTIAE ],	/* INPUT: y cordinates */
	int thetacol[ MAX_BOZORTH_MINUTIAE ],	/* INPUT: theta values */

	int * ncomparisons,			/* OUTPUT: number of pointwise comparisons */
	int cols[][ COLS_SIZE_2 ],		/* OUTPUT: pointwise comparison table */
	int * colptrs[]				/* INPUT and OUTPUT: sorted list of pointers to rows in cols[] */
	)
{
int i, j, k;

int b;
int t;
int n;
int l;

int table_index;

int dx;
int dy;
int distance;

int theta_kj;
int beta_j;
int beta_k;

int * c;



c = &cols[0][0];

table_index = 0;
for ( k = 0; k < npoints - 1; k++ ) {
	for ( j = k + 1; j < npoints; j++ ) {


		if ( thetacol[j] > 0 ) {

			if ( thetacol[k] == thetacol[j] - 180 )
				continue;
		} else {

			if ( thetacol[k] == thetacol[j] + 180 )
				continue;
		}


		dx = xcol[j] - xcol[k];
		dy = ycol[j] - ycol[k];
		distance = SQUARED(dx) + SQUARED(dy);
		if ( distance > SQUARED(DM) ) {
			if ( dx > DM )
				break;
			else
				continue;

		}

					/* The distance is in the range [ 0, 125^2 ] */
		if ( dx == 0 )
			theta_kj = 90;
		else {
			double dz;

			if ( m1_xyt )
				dz = ( 180.0F / PI_SINGLE ) * atanf( (float) -dy / (float) dx );
			else
				dz = ( 180.0F / PI_SINGLE ) * atanf( (float) dy / (float) dx );
			if ( dz < 0.0F )
				dz -= 0.5F;
			else
				dz += 0.5F;
			theta_kj = (int) dz;
		}


		beta_k = theta_kj - thetacol[k];
		beta_k = IANGLE180(beta_k);

		beta_j = theta_kj - thetacol[j] + 180;
		beta_j = IANGLE180(beta_j);


		if ( beta_k < beta_j ) {
			*c++ = distance;
			*c++ = beta_k;
			*c++ = beta_j;
			*c++ = k+1;
			*c++ = j+1;
			*c++ = theta_kj;
		} else {
			*c++ = distance;
			*c++ = beta_j;
			*c++ = beta_k;
			*c++ = k+1;
			*c++ = j+1;
			*c++ = theta_kj + 400;

		}






		b = 0;
		t = table_index + 1;
		l = 1;
		n = -1;			/* Init binary search state ... */




		while ( t - b > 1 ) {
			int * midpoint;

			l = ( b + t ) / 2;
			midpoint = colptrs[l-1];




			for ( i=0; i < 3; i++ ) {
				int dd, ff;

				dd = cols[table_index][i];

				ff = midpoint[i];


				n = SENSE(dd,ff);


				if ( n < 0 ) {
					t = l;
					break;
				}
				if ( n > 0 ) {
					b = l;
					break;
				}
			}

			if ( n == 0 ) {
				n = 1;
				b = l;
			}
		} /* END while */

		if ( n == 1 )
			++l;




		for ( i = table_index; i >= l; --i )
			colptrs[i] = colptrs[i-1];


		colptrs[l-1] = &cols[table_index][0];
		++table_index;


		if ( table_index == 19999 ) {
#ifndef NOVERBOSE
			if ( verbose_bozorth )
				printf( "bz_comp(): breaking loop to avoid table overflow\n" );
#endif
			goto COMP_END;
		}

	} /* END for j */

} /* END for k */

COMP_END:
	*ncomparisons = table_index;

}
Esempio n. 9
0
int bz_match_score(
	int np,
	struct xyt_struct * pstruct,
	struct xyt_struct * gstruct
	)
{
int kx, kq;
int ftt;
int tot;
int qh;
int tp;
int ll, jj, kk, n, t, b;
int k, i, j, ii, z;
int kz, l;
int p1, p2;
int dw, ww;
int match_score;
int qq_overflow = 0;
float fi;

/* These next 3 arrays originally declared global, but moved here */
/* locally because they are only used herein */
int rr[ RR_SIZE ];
int avn[ AVN_SIZE ];
int avv[ AVV_SIZE_1 ][ AVV_SIZE_2 ];

/* These now externally defined in bozorth.h */
/* extern FILE * stderr; */
/* extern char * get_progname( void ); */
/* extern char * get_probe_filename( void ); */
/* extern char * get_gallery_filename( void ); */






if ( pstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
#ifndef NOVERBOSE
	if ( gstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
		if ( verbose_bozorth )
			fprintf( stderr, "%s: bz_match_score(): both probe and gallery file have too few minutiae (%d,%d) to compute a real Bozorth match score; min. is %d [p=%s; g=%s]\n",
						get_progname(),
						pstruct->nrows, gstruct->nrows, MIN_COMPUTABLE_BOZORTH_MINUTIAE,
						get_probe_filename(), get_gallery_filename() );
	} else {
		if ( verbose_bozorth )
			fprintf( stderr, "%s: bz_match_score(): probe file has too few minutiae (%d) to compute a real Bozorth match score; min. is %d [p=%s; g=%s]\n",
						get_progname(),
						pstruct->nrows, MIN_COMPUTABLE_BOZORTH_MINUTIAE,
						get_probe_filename(), get_gallery_filename() );
	}
#endif
	return ZERO_MATCH_SCORE;
}



if ( gstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
#ifndef NOVERBOSE
	if ( verbose_bozorth )
		fprintf( stderr, "%s: bz_match_score(): gallery file has too few minutiae (%d) to compute a real Bozorth match score; min. is %d [p=%s; g=%s]\n",
						get_progname(),
						gstruct->nrows, MIN_COMPUTABLE_BOZORTH_MINUTIAE,
						get_probe_filename(), get_gallery_filename() );
#endif
	return ZERO_MATCH_SCORE;
}









								/* initialize tables to 0's */
INT_SET( (int *) &yl, YL_SIZE_1 * YL_SIZE_2, 0 );



INT_SET( (int *) &sc, SC_SIZE, 0 );
INT_SET( (int *) &cp, CP_SIZE, 0 );
INT_SET( (int *) &rp, RP_SIZE, 0 );
INT_SET( (int *) &tq, TQ_SIZE, 0 );
INT_SET( (int *) &rq, RQ_SIZE, 0 );
INT_SET( (int *) &zz, ZZ_SIZE, 1000 );				/* zz[] initialized to 1000's */

INT_SET( (int *) &avn, AVN_SIZE, 0 );				/* avn[0...4] <== 0; */





tp  = 0;
p1  = 0;
tot = 0;
ftt = 0;
kx  = 0;
match_score = 0;

for ( k = 0; k < np - 1; k++ ) {
					/* printf( "compute(): looping with k=%d\n", k ); */

	if ( sc[k] )			/* If SC counter for current pair already incremented ... */
		continue;		/*		Skip to next pair */


	i = colp[k][1];
	t = colp[k][3];




	qq[0]   = i;
	rq[t-1] = i;
	tq[i-1] = t;


	ww = 0;
	dw = 0;

	do {
		ftt++;
		tot = 0;
		qh  = 1;
		kx  = k;




		do {









			kz = colp[kx][2];
			l  = colp[kx][4];
			kx++;
			bz_sift( &ww, kz, &qh, l, kx, ftt, &tot, &qq_overflow );
			if ( qq_overflow ) {
				fprintf( stderr, "%s: WARNING: bz_match_score(): qq[] overflow from bz_sift() #1 [p=%s; g=%s]\n",
							get_progname(), get_probe_filename(), get_gallery_filename() );
				return QQ_OVERFLOW_SCORE;
			}

#ifndef NOVERBOSE
			if ( verbose_bozorth )
				printf( "x1 %d %d %d %d %d %d\n", kx, colp[kx][0], colp[kx][1], colp[kx][2], colp[kx][3], colp[kx][4] );
#endif

		} while ( colp[kx][3] == colp[k][3] && colp[kx][1] == colp[k][1] );
			/* While the startpoints of lookahead edge pairs are the same as the starting points of the */
			/* current pair, set KQ to lookahead edge pair index where above bz_sift() loop left off */

		kq = kx;

		for ( j = 1; j < qh; j++ ) {
			for ( i = kq; i < np; i++ ) {

				for ( z = 1; z < 3; z++ ) {
					if ( z == 1 ) {
						if ( (j+1) > QQ_SIZE ) {
							fprintf( stderr, "%s: WARNING: bz_match_score(): qq[] overflow #1 in bozorth3(); j-1 is %d [p=%s; g=%s]\n",
								get_progname(), j-1, get_probe_filename(), get_gallery_filename() );
							return QQ_OVERFLOW_SCORE;
						}
						p1 = qq[j];
					} else {
						p1 = tq[p1-1];

					}






					if ( colp[i][2*z] != p1 )
						break;
				}


				if ( z == 3 ) {
					z = colp[i][1];
					l = colp[i][3];



					if ( z != colp[k][1] && l != colp[k][3] ) {
						kx = i + 1;
						bz_sift( &ww, z, &qh, l, kx, ftt, &tot, &qq_overflow );
						if ( qq_overflow ) {
							fprintf( stderr, "%s: WARNING: bz_match_score(): qq[] overflow from bz_sift() #2 [p=%s; g=%s]\n",
								get_progname(), get_probe_filename(), get_gallery_filename() );
							return QQ_OVERFLOW_SCORE;
						}
					}
				}
			} /* END for i */



			/* Done looking ahead for current j */





			l = 1;
			t = np + 1;
			b = kq;

			while ( t - b > 1 ) {
				l = ( b + t ) / 2;

				for ( i = 1; i < 3; i++ ) {

					if ( i == 1 ) {
						if ( (j+1) > QQ_SIZE ) {
							fprintf( stderr, "%s: WARNING: bz_match_score(): qq[] overflow #2 in bozorth3(); j-1 is %d [p=%s; g=%s]\n",
								get_progname(), j-1, get_probe_filename(), get_gallery_filename() );
							return QQ_OVERFLOW_SCORE;
						}
						p1 = qq[j];
					} else {
						p1 = tq[p1-1];
					}



					p2 = colp[l-1][i*2-1];

					n = SENSE(p1,p2);

					if ( n < 0 ) {
						t = l;
						break;
					}
					if ( n > 0 ) {
						b = l;
						break;
					}
				}

				if ( n == 0 ) {






					/* Locates the head of consecutive sequence of edge pairs all having the same starting Subject and On-File edgepoints */
					while ( colp[l-2][3] == p2 && colp[l-2][1] == colp[l-1][1] )
						l--;

					kx = l - 1;


					do {
						kz = colp[kx][2];
						l  = colp[kx][4];
						kx++;
						bz_sift( &ww, kz, &qh, l, kx, ftt, &tot, &qq_overflow );
						if ( qq_overflow ) {
							fprintf( stderr, "%s: WARNING: bz_match_score(): qq[] overflow from bz_sift() #3 [p=%s; g=%s]\n",
								get_progname(), get_probe_filename(), get_gallery_filename() );
							return QQ_OVERFLOW_SCORE;
						}
					} while ( colp[kx][3] == p2 && colp[kx][1] == colp[kx-1][1] );

					break;
				} /* END if ( n == 0 ) */

			} /* END while */

		} /* END for j */




		if ( tot >= MSTR ) {
			jj = 0;
			kk = 0;
			n  = 0;
			l  = 0;

			for ( i = 0; i < tot; i++ ) {


				int colp_value = colp[ y[i]-1 ][0];
				if ( colp_value < 0 ) {
					kk += colp_value;
					n++;
				} else {
					jj += colp_value;
					l++;
				}
			}


			if ( n == 0 ) {
				n = 1;
			} else if ( l == 0 ) {
				l = 1;
			}



			fi = (float) jj / (float) l - (float) kk / (float) n;

			if ( fi > 180.0F ) {
				fi = ( jj + kk + n * 360 ) / (float) tot;
				if ( fi > 180.0F )
					fi -= 360.0F;
			} else {
				fi = ( jj + kk ) / (float) tot;
			}

			jj = ROUND(fi);
			if ( jj <= -180 )
				jj += 360;



			kk = 0;
			for ( i = 0; i < tot; i++ ) {
				int diff = colp[ y[i]-1 ][0] - jj;
				j = SQUARED( diff );




				if ( j > TXS && j < CTXS )
					kk++;
				else
					y[i-kk] = y[i];
			} /* END FOR i */

			tot -= kk;				/* Adjust the total edge pairs TOT based on # of edge pairs skipped */

		} /* END if ( tot >= MSTR ) */




		if ( tot < MSTR ) {




			for ( i = tot-1 ; i >= 0; i-- ) {
				int idx = y[i] - 1;
				if ( rk[idx] == 0 ) {
					sc[idx] = -1;
				} else {
					sc[idx] = rk[idx];
				}
			}
			ftt--;

		} else {		/* tot >= MSTR */
					/* Otherwise size of TOT group (seq. of TOT indices stored in Y) is large enough to analyze */

			int pa = 0;
			int pb = 0;
			int pc = 0;
			int pd = 0;

			for ( i = 0; i < tot; i++ ) {
				int idx = y[i] - 1;
				for ( ii = 1; ii < 4; ii++ ) {




					kk = ( SQUARED(ii) - ii + 2 ) / 2 - 1;




					jj = colp[idx][kk];

					switch ( ii ) {
					  case 1:
						if ( colp[idx][0] < 0 ) {
							pd += colp[idx][0];
							pb++;
						} else {
							pa += colp[idx][0];
							pc++;
						}
						break;
					  case 2:
						avn[ii-1] += pstruct->xcol[jj-1];
						avn[ii] += pstruct->ycol[jj-1];
						break;
					  default:
						avn[ii] += gstruct->xcol[jj-1];
						avn[ii+1] += gstruct->ycol[jj-1];
						break;
					} /* switch */
				} /* END for ii = [1..3] */

				for ( ii = 0; ii < 2; ii++ ) {
					n = -1;
					l = 1;

					for ( jj = 1; jj < 3; jj++ ) {










						p1 = colp[idx][ 2 * ii + jj ];


						b = 0;
						t = yl[ii][tp] + 1;

						while ( t - b > 1 ) {
							l  = ( b + t ) / 2;
							p2 = yy[l-1][ii][tp];
							n  = SENSE(p1,p2);

							if ( n < 0 ) {
								t = l;
							} else {
								if ( n > 0 ) {
									b = l;
								} else {
									break;
								}
							}
						} /* END WHILE */

						if ( n != 0 ) {
							if ( n == 1 )
								++l;

							for ( kk = yl[ii][tp]; kk >= l; --kk ) {
								yy[kk][ii][tp] = yy[kk-1][ii][tp];
							}

							++yl[ii][tp];
							yy[l-1][ii][tp] = p1;


						} /* END if ( n != 0 ) */

						/* Otherwise, edgepoint already stored in YY */

					} /* END FOR jj in [1,2] */
				} /* END FOR ii in [0,1] */
			} /* END FOR i */

			if ( pb == 0 ) {
				pb = 1;
			} else if ( pc == 0 ) {
				pc = 1;
			}



			fi = (float) pa / (float) pc - (float) pd / (float) pb;
			if ( fi > 180.0F ) {

				fi = ( pa + pd + pb * 360 ) / (float) tot;
				if ( fi > 180.0F )
					fi -= 360.0F;
			} else {
				fi = ( pa + pd ) / (float) tot;
			}

			pa = ROUND(fi);
			if ( pa <= -180 )
				pa += 360;



			avv[tp][0] = pa;

			for ( ii = 1; ii < 5; ii++ ) {
				avv[tp][ii] = avn[ii] / tot;
				avn[ii] = 0;
			}

			ct[tp]  = tot;
			gct[tp] = tot;

			if ( tot > match_score )		/* If current TOT > match_score ... */
				match_score = tot;		/*	Keep track of max TOT in match_score */

			ctt[tp]    = 0;		/* Init CTT[TP] to 0 */
			ctp[tp][0] = tp;	/* Store TP into CTP */

			for ( ii = 0; ii < tp; ii++ ) {
				int found;
				int diff;

				int * avv_tp_ptr = &avv[tp][0];
				int * avv_ii_ptr = &avv[ii][0];
				diff = *avv_tp_ptr++ - *avv_ii_ptr++;
				j = SQUARED( diff );






				if ( j > TXS && j < CTXS )
					continue;









				ll = *avv_tp_ptr++ - *avv_ii_ptr++;
				jj = *avv_tp_ptr++ - *avv_ii_ptr++;
				kk = *avv_tp_ptr++ - *avv_ii_ptr++;
				j  = *avv_tp_ptr++ - *avv_ii_ptr++;

				{
				float tt, ai, dz;

				tt = (float) (SQUARED(ll) + SQUARED(jj));
				ai = (float) (SQUARED(j)  + SQUARED(kk));

				fi = ( 2.0F * TK ) * ( tt + ai );
				dz = tt - ai;


				if ( SQUARED(dz) > SQUARED(fi) )
					continue;
				}



				if ( ll ) {

					if ( m1_xyt )
						fi = ( 180.0F / PI_SINGLE ) * atanf( (float) -jj / (float) ll );
					else
						fi = ( 180.0F / PI_SINGLE ) * atanf( (float) jj / (float) ll );
					if ( fi < 0.0F ) {
						if ( ll < 0 )
							fi += 180.5F;
						else
							fi -= 0.5F;
					} else {
						if ( ll < 0 )
							fi -= 180.5F;
						else
							fi += 0.5F;
					}
					jj = (int) fi;
					if ( jj <= -180 )
						jj += 360;
				} else {

					if ( m1_xyt ) {
						if ( jj > 0 )
							jj = -90;
						else
							jj = 90;
					} else {
						if ( jj > 0 )
							jj = 90;
						else
							jj = -90;
					}
				}



				if ( kk ) {

					if ( m1_xyt )
						fi = ( 180.0F / PI_SINGLE ) * atanf( (float) -j / (float) kk );
					else
						fi = ( 180.0F / PI_SINGLE ) * atanf( (float) j / (float) kk );
					if ( fi < 0.0F ) {
						if ( kk < 0 )
							fi += 180.5F;
						else
							fi -= 0.5F;
					} else {
						if ( kk < 0 )
							fi -= 180.5F;
						else
							fi += 0.5F;
					}
					j = (int) fi;
					if ( j <= -180 )
						j += 360;
				} else {

					if ( m1_xyt ) {
						if ( j > 0 )
							j = -90;
						else
							j = 90;
					} else {
						if ( j > 0 )
							j = 90;
						else
							j = -90;
					}
				}





				pa = 0;
				pb = 0;
				pc = 0;
				pd = 0;

				if ( avv[tp][0] < 0 ) {
					pd += avv[tp][0];
					pb++;
				} else {
					pa += avv[tp][0];
					pc++;
				}

				if ( avv[ii][0] < 0 ) {
					pd += avv[ii][0];
					pb++;
				} else {
					pa += avv[ii][0];
					pc++;
				}

				if ( pb == 0 ) {
					pb = 1;
				} else if ( pc == 0 ) {
					pc = 1;
				}



				fi = (float) pa / (float) pc - (float) pd / (float) pb;

				if ( fi > 180.0F ) {
					fi = ( pa + pd + pb * 360 ) / 2.0F;
					if ( fi > 180.0F )
						fi -= 360.0F;
				} else {
					fi = ( pa + pd ) / 2.0F;
				}

				pb = ROUND(fi);
				if ( pb <= -180 )
					pb += 360;





				pa = jj - j;
				pa = IANGLE180(pa);
				kk = SQUARED(pb-pa);




				/* Was: if ( SQUARED(kk) > TXS && kk < CTXS ) : assume typo */
				if ( kk > TXS && kk < CTXS )
					continue;


				found = 0;
				for ( kk = 0; kk < 2; kk++ ) {
					jj = 0;
					ll = 0;

					do {
						while ( yy[jj][kk][ii] < yy[ll][kk][tp] && jj < yl[kk][ii] ) {

							jj++;
						}




						while ( yy[jj][kk][ii] > yy[ll][kk][tp] && ll < yl[kk][tp] ) {

							ll++;
						}




						if ( yy[jj][kk][ii] == yy[ll][kk][tp] && jj < yl[kk][ii] && ll < yl[kk][tp] ) {
							found = 1;
							break;
						}


					} while ( jj < yl[kk][ii] && ll < yl[kk][tp] );
					if ( found )
						break;
				} /* END for kk */

				if ( ! found ) {			/* If we didn't find what we were searching for ... */
					gct[ii] += ct[tp];
					if ( gct[ii] > match_score )
						match_score = gct[ii];
					++ctt[ii];
					ctp[ii][ctt[ii]] = tp;
				}

			} /* END for ii in [0,TP-1] prior TP group */

			tp++;			/* Bump TP counter */


		} /* END ELSE if ( tot == MSTR ) */



		if ( qh > QQ_SIZE ) {
			fprintf( stderr, "%s: WARNING: bz_match_score(): qq[] overflow #3 in bozorth3(); qh-1 is %d [p=%s; g=%s]\n",
					get_progname(), qh-1, get_probe_filename(), get_gallery_filename() );
			return QQ_OVERFLOW_SCORE;
		}
		for ( i = qh - 1; i > 0; i-- ) {
			n = qq[i] - 1;
			if ( ( tq[n] - 1 ) >= 0 ) {
				rq[tq[n]-1] = 0;
				tq[n]       = 0;
				zz[n]       = 1000;
			}
		}

		for ( i = dw - 1; i >= 0; i-- ) {
			n = rr[i] - 1;
			if ( tq[n] ) {
				rq[tq[n]-1] = 0;
				tq[n]       = 0;
			}
		}

		i = 0;
		j = ww - 1;
		while ( i >= 0 && j >= 0 ) {
			if ( nn[j] < mm[j] ) {
				++nn[j];

				for ( i = ww - 1; i >= 0; i-- ) {
					int rt = rx[i];
					if ( rt < 0 ) {
						rt = - rt;
						rt--;
						z  = rf[i][nn[i]-1]-1;



						if (( tq[z] != (rt+1) && tq[z] ) || ( rq[rt] != (z+1) && rq[rt] ))
							break;


						tq[z]  = rt+1;
						rq[rt] = z+1;
						rr[i]  = z+1;
					} else {
						rt--;
						z = cf[i][nn[i]-1]-1;


						if (( tq[rt] != (z+1) && tq[rt] ) || ( rq[z] != (rt+1) && rq[z] ))
							break;


						tq[rt] = z+1;
						rq[z]  = rt+1;
						rr[i]  = rt+1;
					}
				} /* END for i */

				if ( i >= 0 ) {
					for ( z = i + 1; z < ww; z++) {
						n = rr[z] - 1;
						if ( tq[n] - 1 >= 0 ) {
							rq[tq[n]-1] = 0;
							tq[n]       = 0;
						}
					}
					j = ww - 1;
				}

			} else {
				nn[j] = 1;
				j--;
			}

		}

		if ( tp > 1999 )
			break;

		dw = ww;


	} while ( j >= 0 ); /* END while endpoint group remain ... */


	if ( tp > 1999 )
		break;




	n = qq[0] - 1;
	if ( tq[n] - 1 >= 0 ) {
		rq[tq[n]-1] = 0;
		tq[n]       = 0;
	}

	for ( i = ww-1; i >= 0; i-- ) {
		n = rx[i];
		if ( n < 0 ) {
			n = - n;
			rp[n-1] = 0;
		} else {
			cp[n-1] = 0;
		}

	}

} /* END FOR each edge pair */



if ( match_score < MMSTR ) {
	return match_score;
}

match_score = bz_final_loop( tp );
return match_score;
}
Esempio n. 10
0
int bz_match(
	int probe_ptrlist_len,		/* INPUT:  pruned length of Subject's pointer list */
	int gallery_ptrlist_len		/* INPUT:  pruned length of On-File Record's pointer list */
	)
{
int i;			/* Temp index */
int ii;			/* Temp index */
int edge_pair_index;	/* Compatible edge pair index */
float dz;		/* Delta difference and delta angle stats */
float fi;		/* Distance limit based on factor TK */
int * ss;		/* Subject's comparison stats row */
int * ff;		/* On-File Record's comparison stats row */
int j;			/* On-File Record's row index */
int k;			/* Subject's row index */
int st;			/* Starting On-File Record's row index */
int p1;			/* Adjusted Subject's ThetaKJ, DeltaThetaKJs, K or J point index */
int p2;			/* Adjusted On-File's ThetaKJ, RTP point index */
int n;			/* ThetaKJ and binary search state variable */
int l;			/* Midpoint of binary search */
int b;			/* ThetaKJ state variable, and bottom of search range */
int t;			/* Top of search range */

register int * rotptr;


#define ROT_SIZE_1 20000
#define ROT_SIZE_2 5

static int rot[ ROT_SIZE_1 ][ ROT_SIZE_2 ];


static int * rtp[ ROT_SIZE_1 ];




/* These now externally defined in bozorth.h */
/* extern int * scolpt[ SCOLPT_SIZE ];			 INPUT */
/* extern int * fcolpt[ FCOLPT_SIZE ];			 INPUT */
/* extern int   colp[ COLP_SIZE_1 ][ COLP_SIZE_2 ];	 OUTPUT */
/* extern int verbose_bozorth; */
/* extern FILE * stderr; */
/* extern char * get_progname( void ); */
/* extern char * get_probe_filename( void ); */
/* extern char * get_gallery_filename( void ); */




st = 1;
edge_pair_index = 0;
rotptr = &rot[0][0];

/* Foreach sorted edge in Subject's Web ... */

for ( k = 1; k < probe_ptrlist_len; k++ ) {
	ss = scolpt[k-1];

	/* Foreach sorted edge in On-File Record's Web ... */

	for ( j = st; j <= gallery_ptrlist_len; j++ ) {
		ff = fcolpt[j-1];
		dz = *ff - *ss;

		fi = ( 2.0F * TK ) * ( *ff + *ss );








		if ( SQUARED(dz) > SQUARED(fi) ) {
			if ( dz < 0 ) {

				st = j + 1;

				continue;
			} else
				break;


		}



		for ( i = 1; i < 3; i++ ) {
			float dz_squared;

			dz = *(ss+i) - *(ff+i);
			dz_squared = SQUARED(dz);




			if ( dz_squared > TXS && dz_squared < CTXS )
				break;
		}

		if ( i < 3 )
			continue;






		if ( *(ss+5) >= 220 ) {
			p1 = *(ss+5) - 580;
			n  = 1;
		} else {
			p1 = *(ss+5);
			n  = 0;
		}


		if ( *(ff+5) >= 220 ) {
			p2 = *(ff+5) - 580;
			b  = 1;
		} else {
			p2 = *(ff+5);
			b  = 0;
		}

		p1 -= p2;
		p1 = IANGLE180(p1);
























		if ( n != b ) {

			*rotptr++ = p1;
			*rotptr++ = *(ss+3);
			*rotptr++ = *(ss+4);

			*rotptr++ = *(ff+4);
			*rotptr++ = *(ff+3);
		} else {
			*rotptr++ = p1;
			*rotptr++ = *(ss+3);
			*rotptr++ = *(ss+4);

			*rotptr++ = *(ff+3);
			*rotptr++ = *(ff+4);
		}






		n = -1;
		l = 1;
		b = 0;
		t = edge_pair_index + 1;
		while ( t - b > 1 ) {
			l = ( b + t ) / 2;

			for ( i = 0; i < 3; i++ ) {
				static int ii_table[] = { 1, 3, 2 };

								/*	1 = Subject's Kth, */
								/*	3 = On-File's Jth or Kth (depending), */
								/*	2 = Subject's Jth */

				ii = ii_table[i];
				p1 = rot[edge_pair_index][ii];
				p2 = *( rtp[l-1] + ii );

				n = SENSE(p1,p2);

				if ( n < 0 ) {
					t = l;
					break;
				}
				if ( n > 0 ) {
					b = l;
					break;
				}
			}

			if ( n == 0 ) {
				n = 1;
				b = l;
			}
		} /* END while() for binary search */


		if ( n == 1 )
			++l;

		rtp_insert( rtp, l, edge_pair_index, &rot[edge_pair_index][0] );
		++edge_pair_index;

		if ( edge_pair_index == 19999 ) {
#ifndef NOVERBOSE
			if ( verbose_bozorth )
				fprintf( stderr, "%s: bz_match(): WARNING: list is full, breaking loop early [p=%s; g=%s]\n",
							get_progname(), get_probe_filename(), get_gallery_filename() );
#endif
			goto END;		/* break out if list exceeded */
		}

	} /* END FOR On-File (edge) distance */

} /* END FOR Subject (edge) distance */



END:
{
	int * colp_ptr = &colp[0][0];

	for ( i = 0; i < edge_pair_index; i++ ) {
		INT_COPY( colp_ptr, rtp[i], COLP_SIZE_2 );


	}
}



return edge_pair_index;			/* Return the number of compatible edge pairs stored into colp[][] */
}
void SwipeGestureRecognizer::onTouchMoved(const Touch *touch)
{
    if (numTouches() < numTouchesRequired()) {
        return;
    }

    uint64_t deltaTime = touch->timestamp() - m_startTime;
    if (deltaTime == 0) {
        return;
    }

    if (state() != State::Possible) {
        return;
    }

    float prevCentralX = centralX();
    float prevCentralY = centralY();
    updateCentralPoint();
    float deltaX = centralX()  - prevCentralX;
    float deltaY = centralY()  - prevCentralY;
    m_cumulativeDeltaX += deltaX;
    m_cumulativeDeltaY += deltaY;
    float avrgVelocityX = m_cumulativeDeltaX / deltaTime;
    float avrgVelocityY = m_cumulativeDeltaY / deltaTime;
    float cumulativeDeltaSquared = SQUARED_PYTHAGOREAN(m_cumulativeDeltaY, m_cumulativeDeltaX);
    float avrgVelocitySquared = SQUARED_PYTHAGOREAN(avrgVelocityY, avrgVelocityX);
    float thresholdSquared = SQUARED(recognitionThreshold());
    float minDisplacementSquared = SQUARED(minDisplacement());
    float minVelocitySquared = SQUARED(m_minVelocity);
    // qDebug() << m_minVelocity << " " << minDisplacement() << " " << maxDuration();
    // qDebug() << sqrtf(avrgVelocitySquared) << " " << sqrtf(cumulativeDeltaSquared) << " " << deltaTime;

    if (m_noDirection) {
        if (cumulativeDeltaSquared >= thresholdSquared
                && avrgVelocitySquared >= minVelocitySquared
                && cumulativeDeltaSquared >= minDisplacementSquared) {
            setState(State::Recognized);
        }
    } else {
        float absVelocityX  = fabsf(avrgVelocityX);
        float absVelocityY  = fabsf(avrgVelocityY);
        if (absVelocityX > absVelocityY) {
            float absCumulativeDeltaX  = fabsf(m_cumulativeDeltaX);
            if (absCumulativeDeltaX > recognitionThreshold()) {
                if ((deltaX < 0.0f && (m_direction & Left) == 0)
                        || ((deltaX > 0.0f) && (m_direction & Right) == 0)
                        || fabsf(atanf(m_cumulativeDeltaY /m_cumulativeDeltaX)) >= m_maxAngle) {
                    setState(State::Failed);
                } else if (absVelocityX >= m_minVelocity
                           && absCumulativeDeltaX >= minDisplacement()) {
                    setState(State::Recognized);
                }
            }
        } else if (absVelocityY > absVelocityX) {
            float absCumulativeDeltaY  = fabsf(m_cumulativeDeltaY);
            if (absCumulativeDeltaY > recognitionThreshold()) {
                if ((deltaY < 0.0f && (m_direction & Up) == 0)
                        || ((deltaY > 0.0f) && (m_direction & Down) == 0)
                        || fabsf(atanf(m_cumulativeDeltaX / m_cumulativeDeltaY)) >= m_maxAngle) {
                    setState(State::Failed);
                } else if (absVelocityY >= m_minVelocity
                           && absCumulativeDeltaY >= minDisplacement()) {
                    setState(State::Recognized);
                }
            }
        } else if (cumulativeDeltaSquared > thresholdSquared) {
            setState(State::Failed);
        }
    }
}
/** process a variable from the queue of changed variables */
static
SCIP_RETCODE varProcessBoundChanges(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_HEURDATA*        heurdata,           /**< heuristic data */
   SCIP_VAR*             var                 /**< the variable whose bound changes need to be processed */
   )
{
   SCIP_ROW** colrows;
   SCIP_COL* varcol;
   SCIP_Real* colvals;
   SCIP_Real oldmean;
   SCIP_Real newmean;
   SCIP_Real oldvariance;
   SCIP_Real newvariance;
   SCIP_Real oldlb;
   SCIP_Real newlb;
   SCIP_Real oldub;
   SCIP_Real newub;
   SCIP_VARTYPE vartype;
   int ncolrows;
   int r;
   int varindex;

   /* ensure that this is a probing bound change */
   assert(SCIPinProbing(scip));

   assert(var != NULL);
   varcol = SCIPvarGetCol(var);
   assert(varcol != NULL);
   colrows = SCIPcolGetRows(varcol);
   colvals = SCIPcolGetVals(varcol);
   ncolrows = SCIPcolGetNNonz(varcol);

   varindex = SCIPvarGetProbindex(var);

   oldlb = heurdata->currentlbs[varindex];
   oldub = heurdata->currentubs[varindex];

   /* skip update if the variable has never been subject of previously calculated row activities */
   assert((oldlb == SCIP_INVALID) == (oldub == SCIP_INVALID)); /*lint !e777 doesn't like comparing floats for equality */
   if( oldlb == SCIP_INVALID ) /*lint !e777 */
      return SCIP_OKAY;

   newlb = SCIPvarGetLbLocal(var);
   newub = SCIPvarGetUbLocal(var);

   /* skip update if the bound change events have cancelled out */
   if( SCIPisFeasEQ(scip, oldlb, newlb) && SCIPisFeasEQ(scip, oldub, newub) )
      return SCIP_OKAY;

   /* calculate old and new variable distribution mean and variance */
   oldvariance = 0.0;
   newvariance = 0.0;
   oldmean = 0.0;
   newmean = 0.0;
   vartype = SCIPvarGetType(var);
   SCIPvarCalcDistributionParameters(scip, oldlb, oldub, vartype, &oldmean, &oldvariance);
   SCIPvarCalcDistributionParameters(scip, newlb, newub, vartype, &newmean, &newvariance);

   /* loop over all rows of this variable and update activity distribution */
   for( r = 0; r < ncolrows; ++r )
   {
      int rowpos;

      assert(colrows[r] != NULL);
      rowpos = SCIProwGetIndex(colrows[r]);
      assert(rowpos >= 0);

      SCIP_CALL( heurdataEnsureArraySize(scip, heurdata, rowpos) );

      /* only consider rows for which activity distribution was already calculated */
      if( heurdata->rowmeans[rowpos] != SCIP_INVALID ) /*lint !e777 doesn't like comparing floats for equality */
      {
         SCIP_Real coeff;
         SCIP_Real coeffsquared;
         assert(heurdata->rowvariances[rowpos] != SCIP_INVALID
               && SCIPisFeasGE(scip, heurdata->rowvariances[rowpos], 0.0)); /*lint !e777 */

         coeff = colvals[r];
         coeffsquared = SQUARED(coeff);

         /* update variable contribution to row activity distribution */
         heurdata->rowmeans[rowpos] += coeff * (newmean - oldmean);
         heurdata->rowvariances[rowpos] += coeffsquared * (newvariance - oldvariance);
         heurdata->rowvariances[rowpos] = MAX(0.0, heurdata->rowvariances[rowpos]);

         /* account for changes of the infinite contributions to row activities */
         if( coeff > 0.0 )
         {
            /* if the coefficient is positive, upper bounds affect activity up */
            if( SCIPisInfinity(scip, newub) && !SCIPisInfinity(scip, oldub) )
               ++heurdata->rowinfinitiesup[rowpos];
            else if( !SCIPisInfinity(scip, newub) && SCIPisInfinity(scip, oldub) )
               --heurdata->rowinfinitiesup[rowpos];

            if( SCIPisInfinity(scip, newlb) && !SCIPisInfinity(scip, oldlb) )
               ++heurdata->rowinfinitiesdown[rowpos];
            else if( !SCIPisInfinity(scip, newlb) && SCIPisInfinity(scip, oldlb) )
               --heurdata->rowinfinitiesdown[rowpos];
         }
         else if( coeff < 0.0 )
         {
            if( SCIPisInfinity(scip, newub) && !SCIPisInfinity(scip, oldub) )
               ++heurdata->rowinfinitiesdown[rowpos];
            else if( !SCIPisInfinity(scip, newub) && SCIPisInfinity(scip, oldub) )
               --heurdata->rowinfinitiesdown[rowpos];

            if( SCIPisInfinity(scip, newlb) && !SCIPisInfinity(scip, oldlb) )
               ++heurdata->rowinfinitiesup[rowpos];
            else if( !SCIPisInfinity(scip, newlb) && SCIPisInfinity(scip, oldlb) )
               --heurdata->rowinfinitiesup[rowpos];
         }
         assert(heurdata->rowinfinitiesdown[rowpos] >= 0);
         assert(heurdata->rowinfinitiesup[rowpos] >= 0);
      }
   }

   /* store the new local bounds in the data */
   heurdataUpdateCurrentBounds(scip, heurdata, var);

   return SCIP_OKAY;
}
/** calculate the branching score of a variable, depending on the chosen score parameter */
static
SCIP_RETCODE calcBranchScore(
   SCIP*                 scip,               /**< current SCIP */
   SCIP_HEURDATA*        heurdata,           /**< branch rule data */
   SCIP_VAR*             var,                /**< candidate variable */
   SCIP_Real             lpsolval,           /**< current fractional LP-relaxation solution value  */
   SCIP_Real*            upscore,            /**< pointer to store the variable score when branching on it in upward direction */
   SCIP_Real*            downscore,          /**< pointer to store the variable score when branching on it in downward direction */
   char                  scoreparam          /**< the score parameter of this heuristic */
   )
{
   SCIP_COL* varcol;
   SCIP_ROW** colrows;
   SCIP_Real* rowvals;
   SCIP_Real varlb;
   SCIP_Real varub;
   SCIP_Real squaredbounddiff; /* current squared difference of variable bounds (ub - lb)^2 */
   SCIP_Real newub;            /* new upper bound if branching downwards */
   SCIP_Real newlb;            /* new lower bound if branching upwards */
   SCIP_Real squaredbounddiffup; /* squared difference after branching upwards (ub - lb')^2 */
   SCIP_Real squaredbounddiffdown; /* squared difference after branching downwards (ub' - lb)^2 */
   SCIP_Real currentmean;      /* current mean value of variable uniform distribution */
   SCIP_Real meanup;           /* mean value of variable uniform distribution after branching up */
   SCIP_Real meandown;         /* mean value of variable uniform distribution after branching down*/
   SCIP_VARTYPE vartype;
   int ncolrows;
   int i;

   SCIP_Bool onlyactiverows; /* should only rows which are active at the current node be considered? */

   assert(scip != NULL);
   assert(var != NULL);
   assert(upscore != NULL);
   assert(downscore != NULL);
   assert(!SCIPisIntegral(scip, lpsolval) || SCIPvarIsBinary(var));
   assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);

   varcol = SCIPvarGetCol(var);
   assert(varcol != NULL);

   colrows = SCIPcolGetRows(varcol);
   rowvals = SCIPcolGetVals(varcol);
   ncolrows = SCIPcolGetNNonz(varcol);
   varlb = SCIPvarGetLbLocal(var);
   varub = SCIPvarGetUbLocal(var);
   assert(SCIPisFeasLT(scip, varlb, varub));
   vartype = SCIPvarGetType(var);

   /* calculate mean and variance of variable uniform distribution before and after branching */
   currentmean = 0.0;
   squaredbounddiff = 0.0;
   SCIPvarCalcDistributionParameters(scip, varlb, varub, vartype, &currentmean, &squaredbounddiff);

   /* unfixed binary variables may have an integer solution value in the LP solution, eg, at the presence of indicator constraints */
   if( !SCIPvarIsBinary(var) )
   {
      newlb = SCIPfeasCeil(scip, lpsolval);
      newub = SCIPfeasFloor(scip, lpsolval);
   }
   else
   {
      newlb = 1.0;
      newub = 0.0;
   }


   /* calculate the variable's uniform distribution after branching up and down, respectively. */
   squaredbounddiffup = 0.0;
   meanup = 0.0;
   SCIPvarCalcDistributionParameters(scip, newlb, varub, vartype, &meanup, &squaredbounddiffup);

   /* calculate the distribution mean and variance for a variable with finite lower bound */
   squaredbounddiffdown = 0.0;
   meandown = 0.0;
   SCIPvarCalcDistributionParameters(scip, varlb, newub, vartype, &meandown, &squaredbounddiffdown);

   /* initialize the variable's up and down score */
   *upscore = 0.0;
   *downscore = 0.0;

   onlyactiverows = FALSE;

   /* loop over the variable rows and calculate the up and down score */
   for( i = 0; i < ncolrows; ++i )
   {
      SCIP_ROW* row;
      SCIP_Real changedrowmean;
      SCIP_Real rowmean;
      SCIP_Real rowvariance;
      SCIP_Real changedrowvariance;
      SCIP_Real currentrowprob;
      SCIP_Real newrowprobup;
      SCIP_Real newrowprobdown;
      SCIP_Real squaredcoeff;
      SCIP_Real rowval;
      int rowinfinitiesdown;
      int rowinfinitiesup;
      int rowpos;

      row = colrows[i];
      rowval = rowvals[i];
      assert(row != NULL);

      /* we access the rows by their index */
      rowpos = SCIProwGetIndex(row);

      /* skip non-active rows if the user parameter was set this way */
      if( onlyactiverows && SCIPisSumPositive(scip, SCIPgetRowLPFeasibility(scip, row)) )
         continue;

      /* call method to ensure sufficient data capacity */
      SCIP_CALL( heurdataEnsureArraySize(scip, heurdata, rowpos) );

      /* calculate row activity distribution if this is the first candidate to appear in this row */
      if( heurdata->rowmeans[rowpos] == SCIP_INVALID ) /*lint !e777 doesn't like comparing floats for equality */
      {
         rowCalculateGauss(scip, heurdata, row, &heurdata->rowmeans[rowpos], &heurdata->rowvariances[rowpos],
               &heurdata->rowinfinitiesdown[rowpos], &heurdata->rowinfinitiesup[rowpos]);
      }

      /* retrieve the row distribution parameters from the branch rule data */
      rowmean = heurdata->rowmeans[rowpos];
      rowvariance = heurdata->rowvariances[rowpos];
      rowinfinitiesdown = heurdata->rowinfinitiesdown[rowpos];
      rowinfinitiesup = heurdata->rowinfinitiesup[rowpos];
      assert(!SCIPisNegative(scip, rowvariance));

      currentrowprob = SCIProwCalcProbability(scip, row, rowmean, rowvariance,
            rowinfinitiesdown, rowinfinitiesup);

      /* get variable's current expected contribution to row activity */
      squaredcoeff = SQUARED(rowval);

      /* first, get the probability change for the row if the variable is branched on upwards. The probability
       * can only be affected if the variable upper bound is finite
       */
      if( !SCIPisInfinity(scip, varub) )
      {
         int rowinftiesdownafterbranch;
         int rowinftiesupafterbranch;

         /* calculate how branching would affect the row parameters */
         changedrowmean = rowmean + rowval * (meanup - currentmean);
         changedrowvariance = rowvariance + squaredcoeff * (squaredbounddiffup - squaredbounddiff);
         changedrowvariance = MAX(0.0, changedrowvariance);

         rowinftiesdownafterbranch = rowinfinitiesdown;
         rowinftiesupafterbranch = rowinfinitiesup;

         /* account for changes of the row's infinite bound contributions */
         if( SCIPisInfinity(scip, -varlb) && rowval < 0.0 )
            rowinftiesupafterbranch--;
         if( SCIPisInfinity(scip, -varlb) && rowval > 0.0 )
            rowinftiesdownafterbranch--;

         assert(rowinftiesupafterbranch >= 0);
         assert(rowinftiesdownafterbranch >= 0);
         newrowprobup = SCIProwCalcProbability(scip, row, changedrowmean, changedrowvariance, rowinftiesdownafterbranch,
               rowinftiesupafterbranch);
      }
      else
         newrowprobup = currentrowprob;

      /* do the same for the other branching direction */
      if( !SCIPisInfinity(scip, varlb) )
      {
         int rowinftiesdownafterbranch;
         int rowinftiesupafterbranch;

         changedrowmean = rowmean + rowval * (meandown - currentmean);
         changedrowvariance = rowvariance + squaredcoeff * (squaredbounddiffdown - squaredbounddiff);
         changedrowvariance = MAX(0.0, changedrowvariance);

         rowinftiesdownafterbranch = rowinfinitiesdown;
         rowinftiesupafterbranch = rowinfinitiesup;

         /* account for changes of the row's infinite bound contributions */
         if( SCIPisInfinity(scip, varub) && rowval > 0.0 )
            rowinftiesupafterbranch -= 1;
         if( SCIPisInfinity(scip, varub) && rowval < 0.0 )
            rowinftiesdownafterbranch -= 1;

         assert(rowinftiesdownafterbranch >= 0);
         assert(rowinftiesupafterbranch >= 0);
         newrowprobdown = SCIProwCalcProbability(scip, row, changedrowmean, changedrowvariance, rowinftiesdownafterbranch,
               rowinftiesupafterbranch);
      }
      else
         newrowprobdown = currentrowprob;

      /* update the up and down score depending on the chosen scoring parameter */
      SCIP_CALL( SCIPupdateDistributionScore(scip, currentrowprob, newrowprobup, newrowprobdown, upscore, downscore, scoreparam) );

      SCIPdebugMessage("  Variable %s changes probability of row %s from %g to %g (branch up) or %g;\n",
         SCIPvarGetName(var), SCIProwGetName(row), currentrowprob, newrowprobup, newrowprobdown);
      SCIPdebugMessage("  -->  new variable score: %g (for branching up), %g (for branching down)\n",
         *upscore, *downscore);
   }

   return SCIP_OKAY;
}
/** calculates the initial mean and variance of the row activity normal distribution.
 *
 *  The mean value \f$ \mu \f$ is given by \f$ \mu = \sum_i=1^n c_i * (lb_i +ub_i) / 2 \f$ where
 *  \f$n \f$ is the number of variables, and \f$ c_i, lb_i, ub_i \f$ are the variable coefficient and
 *  bounds, respectively. With the same notation, the variance \f$ \sigma^2 \f$ is given by
 *  \f$ \sigma^2 = \sum_i=1^n c_i^2 * \sigma^2_i \f$, with the variance being
 *  \f$ \sigma^2_i = ((ub_i - lb_i + 1)^2 - 1) / 12 \f$ for integer variables and
 *  \f$ \sigma^2_i = (ub_i - lb_i)^2 / 12 \f$ for continuous variables.
 */
static
void rowCalculateGauss(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_HEURDATA*        heurdata,           /**< the heuristic rule data */
   SCIP_ROW*             row,                /**< the row for which the gaussian normal distribution has to be calculated */
   SCIP_Real*            mu,                 /**< pointer to store the mean value of the gaussian normal distribution */
   SCIP_Real*            sigma2,             /**< pointer to store the variance value of the gaussian normal distribution */
   int*                  rowinfinitiesdown,  /**< pointer to store the number of variables with infinite bounds to DECREASE activity */
   int*                  rowinfinitiesup     /**< pointer to store the number of variables with infinite bounds to INCREASE activity */
   )
{
   SCIP_COL** rowcols;
   SCIP_Real* rowvals;
   int nrowvals;
   int c;

   assert(scip != NULL);
   assert(row != NULL);
   assert(mu != NULL);
   assert(sigma2 != NULL);
   assert(rowinfinitiesup != NULL);
   assert(rowinfinitiesdown != NULL);

   rowcols = SCIProwGetCols(row);
   rowvals = SCIProwGetVals(row);
   nrowvals = SCIProwGetNNonz(row);

   assert(nrowvals == 0 || rowcols != NULL);
   assert(nrowvals == 0 || rowvals != NULL);

   *mu = SCIProwGetConstant(row);
   *sigma2 = 0.0;
   *rowinfinitiesdown = 0;
   *rowinfinitiesup = 0;

   /* loop over nonzero row coefficients and sum up the variable contributions to mu and sigma2 */
   for( c = 0; c < nrowvals; ++c )
   {
      SCIP_VAR* colvar;
      SCIP_Real colval;
      SCIP_Real colvarlb;
      SCIP_Real colvarub;
      SCIP_Real squarecoeff;
      SCIP_Real varvariance;
      SCIP_Real varmean;
      int varindex;

      assert(rowcols[c] != NULL);
      colvar = SCIPcolGetVar(rowcols[c]);
      assert(colvar != NULL);

      colval = rowvals[c];
      colvarlb = SCIPvarGetLbLocal(colvar);
      colvarub = SCIPvarGetUbLocal(colvar);

      varmean = 0.0;
      varvariance = 0.0;
      varindex = SCIPvarGetProbindex(colvar);
      assert((heurdata->currentlbs[varindex] == SCIP_INVALID)
            == (heurdata->currentubs[varindex] == SCIP_INVALID)); /*lint !e777 doesn't like comparing floats for equality */

      /* variable bounds need to be watched from now on */
      if( heurdata->currentlbs[varindex] == SCIP_INVALID ) /*lint !e777 doesn't like comparing floats for equality */
         heurdataUpdateCurrentBounds(scip, heurdata, colvar);

      assert(!SCIPisInfinity(scip, colvarlb));
      assert(!SCIPisInfinity(scip, -colvarub));
      assert(SCIPisFeasLE(scip, colvarlb, colvarub));

      /* variables with infinite bounds are skipped for the calculation of the variance; they need to
       * be accounted for by the counters for infinite row activity decrease and increase and they
       * are used to shift the row activity mean in case they have one nonzero, but finite bound */
      if( SCIPisInfinity(scip, -colvarlb) || SCIPisInfinity(scip, colvarub) )
      {
         if( SCIPisInfinity(scip, colvarub) )
         {
         /* an infinite upper bound gives the row an infinite maximum activity or minimum activity, if the coefficient is
          * positive or negative, resp.
          */
            if( colval < 0.0 )
               ++(*rowinfinitiesdown);
            else
               ++(*rowinfinitiesup);
         }

         /* an infinite lower bound gives the row an infinite maximum activity or minimum activity, if the coefficient is
          * negative or positive, resp.
          */
         if( SCIPisInfinity(scip, -colvarlb) )
         {
            if( colval > 0.0 )
               ++(*rowinfinitiesdown);
            else
               ++(*rowinfinitiesup);
         }
      }
      SCIPvarCalcDistributionParameters(scip, colvarlb, colvarub, SCIPvarGetType(colvar), &varmean, &varvariance);

      /* actual values are updated; the contribution of the variable to mu is the arithmetic mean of its bounds */
      *mu += colval * varmean;

      /* the variance contribution of a variable is c^2 * (u - l)^2 / 12.0 for continuous and c^2 * ((u - l + 1)^2 - 1) / 12.0 for integer */
      squarecoeff = SQUARED(colval);
      *sigma2 += squarecoeff * varvariance;

      assert(!SCIPisFeasNegative(scip, *sigma2));
   }

   SCIPdebug( SCIPprintRow(scip, row, NULL) );
   SCIPdebugMessage("  Row %s has a mean value of %g at a sigma2 of %g \n", SCIProwGetName(row), *mu, *sigma2);
}