ClothSimulation::Link ClothSimulation::createLink(const float4& posA, const float4& posB, u32 idxA, u32 idxB, float massA, float massB, float dampingFactor )
{
	Link link( idxA, idxB );
	link.m_dampingFactor = dampingFactor;
	link.m_restLength = length3( posB-posA );

	if( massA == FLT_MAX && massB == FLT_MAX )
	{
		link.m_aWeight = 0;
		link.m_bWeight = 0;
	}
	else if( massA == FLT_MAX )
	{
		link.m_aWeight = 0;
		link.m_bWeight = 1;
	}
	else if( massB == FLT_MAX )
	{
		link.m_aWeight = 1;
		link.m_bWeight = 0;
	}
	else
	{
		float massAB = massA + massB;
		link.m_aWeight = massA/massAB;
		link.m_bWeight = massB/massAB;
	}
	return link;
}
Example #2
0
GLdouble dist3(GLdouble p[3], GLdouble q[3])
{
    GLdouble d[3];

    diff3(p, q, d);
    return length3(d);
}
// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CAiwImagePrintIf::ConstructL()
    {
    
    TFileName file( KResource );
    file = PathInfo::RomRootPath();
    TBuf<KResource> length2(KResourceFile);    
    file.SetLength(KDriver + length2.Length());
    file.Replace(KDriver, length2.Length(), KResourceFile);
    
    BaflUtils::NearestLanguageFile( iEikEnv.FsSession(), file );
    iResourceOffset = iEikEnv.AddResourceFileL( file );
    iDRM = DRMCommon::NewL();
    User::LeaveIfError( iDRM->Connect() );
    iNumberOfUnSuppFiles = 0;
    
    
    TFileName printNameFile( KResource ); 
    printNameFile = PathInfo::PhoneMemoryRootPath(); 
    TBuf<KResource> length3(KParamFile);
    printNameFile.SetLength(KDriver + length3.Length());
    printNameFile.Replace(KDriver, length3.Length(), KParamFile); 
    
    iPrintFileName = HBufC::NewL(printNameFile.Length() );
    iPrintFileName->Des().Copy(printNameFile);
    
    TFileName unSuppFile( KResource ); 
    unSuppFile = PathInfo::PhoneMemoryRootPath(); 
    TBuf<KResource> lengthUn(KUnSuppFile);
    unSuppFile.SetLength(KDriver + lengthUn.Length());
    unSuppFile.Replace(KDriver, lengthUn.Length(), KUnSuppFile);
    
    iUnsuppFileName = HBufC::NewL(unSuppFile.Length() );
    iUnsuppFileName->Des().Copy(unSuppFile);
    
    }
void ClothSimulation::solve( float4* v, const Link& link )
{
	float4 ab = v[link.m_b] - v[link.m_a];
	float stretch = length3( ab ) - link.m_restLength;
	stretch *= (1.f-link.m_dampingFactor);
	float4 dx = stretch * normalize3( ab );
	v[link.m_a] += dx*link.m_aWeight;
	v[link.m_b] -= dx*link.m_bWeight;
}
Example #5
0
VEC3	*normalized3(VEC3 *vec)
{
	float	length;

	length = length3(vec);
	vec->x /= length;
	vec->y /= length;
	vec->z /= length;
	return (vec);
}
Example #6
0
CL_Vec4<Type> &CL_Vec4<Type>::normalize3()
{
	Type f = length3();
	if (f!=0)
	{
		x /= f;
		y /= f;
		z /= f;
	}
	return *this;
}
void ClothSimulation::volumeConstraint( float4* vtx, float* mass, const int4* tris, int nTris, float initVolume, float coeff )
{
	float vol = calcVolume( vtx, tris, nTris );

	float force = (vol - initVolume)*coeff;

	int nVtx = 0;
	for(int i=0; i<nTris; i++)
	{
		nVtx = max2( nVtx, max2( tris[i].x, max2( tris[i].y, tris[i].z) ) );
	}
	nVtx += 1;

	float4* disp = new float4[nVtx];
	for(int i=0; i<nVtx; i++) disp[i] = make_float4(0,0,0,0);

	for(int i=0; i<nTris; i++)
	{
		const int4& t = tris[i];
		float4& v0 = vtx[t.x];
		float4& v1 = vtx[t.y];
		float4& v2 = vtx[t.z];

		const float4 n = cross3(v1-v0, v2-v0 );
		float nl = length3( n );
		float area = nl/2.f;

//		force = max2( 0.f, force );
		force = min2( 0.f, force );

		float4 f = force/3.f*(n/nl);
		if( mass[t.x] != FLT_MAX )
			disp[t.x] += f;
//			v0 += f;
		if( mass[t.y] != FLT_MAX )
			disp[t.y] += f;
//			v1 += f;
		if( mass[t.z] != FLT_MAX )
			disp[t.z] += f;
//			v2 += f;
	}

	for(int i=0; i<nVtx; i++)
		vtx[i] += disp[i];

	delete [] disp;
}
Example #8
0
void TestStyles::testCopyParagraphStyle()
{
    QTextLength length1(QTextLength::FixedLength, 10.0);
    QTextLength length2(QTextLength::FixedLength, 20.0);
    QTextLength length3(QTextLength::FixedLength, 30.0);

    KoParagraphStyle style1;
    KoParagraphStyle style2;
    style2.setParentStyle(&style1);

    style1.setLeftMargin(length1);
    style1.setRightMargin(length3);
    style2.setRightMargin(length2);

    KoParagraphStyle newStyle;
    newStyle.copyProperties(&style2);
    QCOMPARE(newStyle.leftMargin(), 10.0);
    QCOMPARE(newStyle.rightMargin(), 20.0);
}
Example #9
0
static FuncResult set_objective_function(
	ObjectiveFunction	objective_function,
	MatrixPair			*matrix_pair)
{
	int		i;

	/*
	 *	Read the objective function from the first matrix on the list.
	 *	Recall from above that we want to maximize
	 *
	 *		h = m00 + (m01 - m10)dx + (m02 - m20)dy + (m03 - m30)dz.
	 *
	 *	Note that the object function is the same for matrix_pair[0] and
	 *	matrix_pair[1], because they are inverses.  (This follows from the
	 *	rule for computing inverses in O(3,1)  (see o31_invert() in
	 *	o31_matrices.c), as well as from the geometrical fact that an
	 *	isometry and its inverse must translate the basepoint equal amounts.)
	 *
	 *	Return
	 *		func_OK		if the objective function's derivative is nonzero, or
	 *		func_failed if it isn't.
	 */

	/*
	 *	Compute the objective function.
	 */

	for (i = 0; i < 3; i++)
		objective_function[i] = matrix_pair->m[0][0][i+1] - matrix_pair->m[0][i+1][0];

	objective_function[3] = matrix_pair->m[0][0][0];

	/*
	 *	Check whether the derivative is nonzero.
	 */

	if (length3(objective_function) > DERIVATIVE_EPSILON)
		return func_OK;
	else
		return func_failed;
}
Example #10
0
inline void projectedOnto3(vec3 * r, vec3 a, vec3 b) {
	mult3( r, a, dot3(a, b) );
	invScale3( r, length3(a) * length3(b) );
}
Example #11
0
int PP6Muon() {
  std::string muonFile;
  int resultCode(0);

  // Obtain filename from user
  std::cout << "Enter filename to analyse: ";
  muonFile = getString();

  std::string runID("run4.dat");
  int numberOfMuons(0), numberOfAntiMuons(0);

  // Count number of muons/antimuons in input file
  resultCode = countMuons(muonFile, runID, numberOfMuons, numberOfAntiMuons);
  if (resultCode) {
    std::cerr << "[PP6Muon:error] Failed to count muons in "
              << muonFile
              << std::endl;
    return resultCode;
  }

  //--------------------------------------------------------------------
  // - Create arrays to hold muon data
  int *muonEventNumber(new int[numberOfMuons]);
  double *muonEnergy(new double[numberOfMuons]);
  double *muonPx(new double[numberOfMuons]);
  double *muonPy(new double[numberOfMuons]);
  double *muonPz(new double[numberOfMuons]);

  int *antimuonEventNumber(new int[numberOfAntiMuons]);
  double *antimuonEnergy(new double[numberOfAntiMuons]);
  double *antimuonPx(new double[numberOfAntiMuons]);
  double *antimuonPy(new double[numberOfAntiMuons]);
  double *antimuonPz(new double[numberOfAntiMuons]);

  // - Read in data
  int eventNumber(0);
  std::string particleName, dataID;
  double particlePx(0), particlePy(0), particlePz(0);
  double particlePtot(0);
  const double muonMass(0.105658366);

  FileReader muonReader(muonFile);
  int muonCounter(0);
  int antimuonCounter(0);
  
  while (muonReader.nextLine()) {
     // Valid lines should begin with an integer, continue without error
    // to skip header
    eventNumber = muonReader.getField<int>(1);
    if (muonReader.inputFailed()) continue;

    particleName = muonReader.getField<std::string>(2);
    if (muonReader.inputFailed()) {
      std::cerr << "[PP6Muon:error] Field 2 of "
                << muonFile
                << " is not a string"
                << std::endl;
      break;
    }

    dataID = muonReader.getField<std::string>(6);
    if (muonReader.inputFailed()) {
      std::cerr << "[PP6Muon:error] Field 6 of "
                << muonFile
                << " is not a string"
                << std::endl;
      break;
    }

    if (dataID == runID) {
      // Read the physics data
      particlePx = muonReader.getField<double>(3);
      if (muonReader.inputFailed()) {
      std::cerr << "[PP6Muon:error] Field 3 of "
                << muonFile
                << " is not a double"
                << std::endl;
      break;
      }

      particlePy = muonReader.getField<double>(4);
      if (muonReader.inputFailed()) {
      std::cerr << "[PP6Muon:error] Field 4 of "
                << muonFile
                << " is not a double"
                << std::endl;
      break;
      }

      particlePz = muonReader.getField<double>(5);
      if (muonReader.inputFailed()) {
      std::cerr << "[PP6Muon:error] Field 5 of "
                << muonFile
                << " is not a double"
                << std::endl;
      break;
      }

      if (particleName == "mu-") {
        // Fill muon data
        muonEventNumber[muonCounter] = eventNumber;
        muonPx[muonCounter] = particlePx;
        muonPy[muonCounter] = particlePy;
        muonPz[muonCounter] = particlePz;
        length3(particlePx, particlePy, particlePz, particlePtot);
        muonEnergy[muonCounter] = sqrt(particlePtot * particlePtot +
                                       muonMass*muonMass);
        ++muonCounter;
      }
      if (particleName == "mu+") {
        // Fill antimuon data
        antimuonEventNumber[antimuonCounter] = eventNumber;
        antimuonPx[antimuonCounter] = particlePx;
        antimuonPy[antimuonCounter] = particlePy;
        antimuonPz[antimuonCounter] = particlePz;
        length3(particlePx, particlePy, particlePz, particlePtot);
        antimuonEnergy[antimuonCounter] = sqrt(particlePtot * particlePtot +
                                           muonMass*muonMass);
        ++antimuonCounter;
      }
    }
  }

  if (muonReader.inputFailed()) {
    // - Clean up and return
    std::cerr << "[PP6Muon:error] Failed to extract physics data from "
              << muonFile
              << std::endl;
    delete [] muonEventNumber;
    delete [] muonEnergy;
    delete [] muonPx;
    delete [] muonPy;
    delete [] muonPz;

    delete [] antimuonEventNumber;
    delete [] antimuonEnergy;
    delete [] antimuonPx;
    delete [] antimuonPy;
    delete [] antimuonPz;
    return 1;
  }

  //--------------------------------------------------------------------
  // - Analyse data...
  // Invariant mass and indexing array
  double *invariantMass(new double[numberOfMuons * numberOfAntiMuons]);
  int *muonPairIndex(new int[numberOfMuons * numberOfAntiMuons]);
  
  // - Loop over mu-/mu+ arrays, calculating invariant masses as we go
  for (int i(0); i < numberOfAntiMuons; ++i) {
    for (int j(0); j < numberOfMuons; ++j) {
      inv_mass(muonEnergy[i], muonPx[i], muonPy[i], muonPz[i],
               antimuonEnergy[j], antimuonPx[j], antimuonPy[j],
               antimuonPz[j],
               invariantMass[i*numberOfMuons + j]);
      muonPairIndex[i*numberOfMuons + j] = i*numberOfMuons + j;
    }
  }

  // Use associative sort to sort masses
  associative_sort(invariantMass, muonPairIndex,
                   numberOfMuons * numberOfAntiMuons);
  
  //--------------------------------------------------------------------
  // - Present results
  //
  std::cout << "Results:" << std::endl;
  std::cout << "========" << std::endl;
  std::cout << "Analysed File : " << muonFile << std::endl;
  std::cout << "Number of Muons = " << numberOfMuons << std::endl;
  std::cout << "Number of AntiMuons = " << numberOfAntiMuons << std::endl;
  std::cout << "----------------------------" << std::endl;

  for (int i(0); i < 10; ++i) {
    int muonIndex(muonPairIndex[i] % numberOfMuons);
    int antimuonIndex((muonPairIndex[i] - muonIndex) / numberOfMuons);

    std::cout << "{InvariantMass : " << invariantMass[muonPairIndex[i]]
              << ",\n\t"
              << "{Muon : "
              << "Event = " << muonEventNumber[muonIndex] << ", "
              << "(E, P) = ("
              << muonEnergy[muonIndex] << ", "
              << muonPx[muonIndex] << ", "
              << muonPy[muonIndex] << ", "
              << muonPz[muonIndex] << ")}\n\t"
              << "{AntiMuon : "
              << "Event = " << antimuonEventNumber[antimuonIndex] << ", "
              << "(E, P) = ("
              << antimuonEnergy[antimuonIndex] << ", "
              << antimuonPx[antimuonIndex] << ", "
              << antimuonPy[antimuonIndex] << ", "
              << antimuonPz[antimuonIndex] << ")}\n"
              << "}"
              << std::endl;
  }


  // - Clean up arrays
  delete [] muonEventNumber;
  delete [] muonEnergy;
  delete [] muonPx;
  delete [] muonPy;
  delete [] muonPz;

  delete [] antimuonEventNumber;
  delete [] antimuonEnergy;
  delete [] antimuonPx;
  delete [] antimuonPy;
  delete [] antimuonPz;

  delete [] invariantMass;
  delete [] muonPairIndex;

  return 0;
}
Example #12
0
	Angle Vec4<Type>::angle3(const Vec4<Type>& v) const
	{
		return Angle(acosf(float(dot3(v) / (length3()*v.length3()))), angle_radians);
	}
Example #13
0
inline void projectOnto3(vec3 a, vec3 * r) {
	scalar l = length3(a) * length3(*r);
	mult3( r, a, dot3(a, *r) );
	invScale3( r, l );
}
Example #14
0
CL_Angle CL_Vec4<Type>::angle3(const CL_Vec4<Type>& v) const
{
	return CL_Angle(acosf(float(dot3(v)/(length3()*v.length3()))), cl_radians);
}
Example #15
0
static void regular_constraints(
	Constraint			*constraints,
	MatrixPairList		*gen_list,
	ObjectiveFunction	objective_function,
	Boolean				*may_be_saddle_point)
{
	/*
	 *	The documentation at the top of this file shows that the image
	 *	height h corresponding to a matrix m is
	 *
	 *		h = m00 + (m01 - m10)dx + (m02 - m20)dy + (m03 - m30)dz.
	 *
	 *	Each regular constraint will say that the image height h for the
	 *	given matrix must remain greater than the image height h' of the
	 *	matrix used for the objective function.  In symbols, h >= h'.
	 *	Since a Constraint says that some quantity must remain negative,
	 *	we express the constraint as h' - h <= 0.
	 *
	 *	The Boolean *may_be_saddle_point will be set to TRUE if some
	 *	constraint suggests a saddle point.  Otherwise it gets set to FALSE.
	 */

	int			i;
	MatrixPair	*matrix_pair;
	Constraint	*constraint;
	double		h[4],
				c;

	/*
	 *	Assume we're not at a saddle point unless we encounter
	 *	evidence to the contrary.
	 */
	*may_be_saddle_point = FALSE;

	/*
	 *	Skip the identity and the MatrixPair used to define the objective
	 *	function, and begin with the next MatrixPair on the list.
	 *	Write a constraint for it and each successive MatrixPair.
	 *
	 *	Skip the first three Constraints in the constraints array.
	 *	They contain the step size constraints.
	 */

	for (	matrix_pair = gen_list->begin.next->next->next,
				constraint = constraints + 3;

			matrix_pair != &gen_list->end;

			matrix_pair = matrix_pair->next,
				constraint++)
	{
		/*
		 *	Compute h.  (As explained in set_objective_function(),
		 *	it doesn't matter which of the two matrices we use.)
		 */

		for (i = 0; i < 3; i++)
			h[i] = matrix_pair->m[0][0][i+1] - matrix_pair->m[0][i+1][0];

		h[3] = matrix_pair->m[0][0][0];

		/*
		 *	Set the constraint to h' - h.
		 *	(The objective function is h' in the above notation.)
		 */

		for (i = 0; i < 4; i++)
			(*constraint)[i] = objective_function[i] - h[i];

		/*
		 *	Does the constraint plane pass through the origin?
		 */

		if ((*constraint)[3] > - CONSTRAINT_EPSILON)
		{
			/*
			 *	Does the constraint have nonzero derivative?
			 *	If not, then h and h' must have equal but nonzero derivatives.
			 *	We know h' has nonzero derivative because we checked it
			 *	when we computed the objective function.
			 *	Its OK for h and h' to have equal but nonzero derivatives --
			 *	it simply means that as we move avoid from the closest
			 *	translate of the basepoint, we're moving away from some
			 *	other translate as well -- be we don't want to divide by
			 *	length3(*constraint).
			 */

			if (length3(*constraint) > ZERO_DERIV_EPSILON)
			{
				/*
				 *	Check whether the constraint plane is parallel
				 *	to the level sets of the objective function.
				 *
				 *	Use the formula <u,v> = |u| |v| cos(angle).
				 */

				c = inner3(objective_function, *constraint) /
						(length3(objective_function) * length3(*constraint));

				/*
				 *	If it is parallel, set *may_be_saddle_point to TRUE.
				 */

				if (fabs(c) > 1.0 - SADDLE_EPSILON)
					*may_be_saddle_point = TRUE;

				/*
				 *	If necessary we could be more sophisticated at this point,
				 *	and check whether the gradients of h and h' are parallel
				 *	or antiparallel.  Typically one expects them to be
				 *	antiparallel (the MatrixPairs are, after all, the face
				 *	pairings of a Dirichlet domain, so we don't have to worry
				 *	about squares of a matrix), but if they were parallel one
				 *	might want to ask which is longer (depending on which is
				 *	longer, you will or will not be able to move the basepoint
				 *	in that direction).
				 */
			}
		}
	}
}
Example #16
0
inline void normalize3(vec3 * r) {
	scalar l = length3( *r );
	invScale3( r, l );
}
Example #17
0
float sphere(vec3 p, float radius)
{
	return length3(p) - radius;
}
Example #18
0
void maximize_the_injectivity_radius(
	MatrixPairList			*gen_list,
	Boolean					*basepoint_moved,
	DirichletInteractivity	interactivity)
{
	int					num_matrix_pairs;
	double				distance_moved,
						prev_distance_moved,
						total_distance_moved;
	Boolean				keep_going;
	ObjectiveFunction	objective_function;
	int					num_constraints;
	Constraint			*constraints;
	Solution			solution;
	Boolean				may_be_saddle_point,
						saddle_query_given;
	int					choice;

	static const Solution	zero_solution = {0.0, 0.0, 0.0},
							small_displacement = {0.001734, 0.002035, 0.000721};

	const static char		*saddle_message = "The basepoint may be at a saddle point of the injectivity radius function.";
	const static int		num_saddle_responses = 2;
	const static char		*saddle_responses[2] = {
								"Continue On",
								"Stop Here and See Dirichlet Domain"};
	const static int		saddle_default = 1;

	const static char		*zero_deriv_message = "The derivative of the distance to the closest translate of the basepoint is zero.";
	const static char		num_zero_deriv_responses = 2;
	const static char		*zero_deriv_responses[2] = {
								"Displace Basepoint and Continue On",
								"Stop Here and See Dirichlet Domain"};
	const static int		zero_deriv_default = 1;


	/*
	 *	Count the number of MatrixPairs.
	 */
	num_matrix_pairs = count_matrix_pairs(gen_list);

	/*
	 *	Make sure that
	 *
	 *	(1)	the identity and at least two other MatrixPairs are present,
	 *
	 *	(2)	the MatrixPairs are in order of increasing height.
	 *
	 *	Technical notes:  We don't really need to have the gen_list
	 *	completely sorted -- it would be enough to have the identity come
	 *	first and the element of lowest image height come immediately after.
	 *	But I think the algorithm will run a tad faster if all elements are
	 *	in order of increasing image height.  That way we get to the
	 *	meaningful constraints first.
	 */
	verify_gen_list(gen_list, num_matrix_pairs);

	/*
	 *	Initialize *basepoint_moved to FALSE.
	 *	If we later move the basepoint, we'll set *basepoint_moved to TRUE.
	 */
	*basepoint_moved = FALSE;

	/*
	 *	Keep track of the total distance we've moved the basepoint.
	 *	We don't want to go too far without recomputing the Dirichlet
	 *	domain to get a fresh set of group elements.
	 */
	total_distance_moved = 0.0;

	/*
	 *	Some ad hoc code for handling low precision situations
	 *	needs to keep track of the prev_distance_moved.
	 */
	prev_distance_moved = DBL_MAX;

	/*
	 *	We don't want to bother the user with the saddle query
	 *	more than once.  We initialize saddle_query_given to FALSE,
	 *	and then set it to TRUE if and when the query takes place.
	 */
	saddle_query_given = FALSE;

	/*
	 *	We want to move the basepoint to a local maximum of the injectivity
	 *	radius function.  Solve the linear approximation to this problem,
	 *	and repeat until a solution is found.
	 */
	do
	{
		/*
		 *	Set the objective function using the first nonidentity matrix
		 *	on the list.  If the derivative of the objective function is
		 *	nonzero, proceed normally.  Otherwise ask the user how s/he
		 *	would like to proceed.
		 */

		if (set_objective_function(objective_function, gen_list->begin.next->next) == func_OK)
		{
			/*
			 *	Allocate space for the Constraints.
			 *	There'll be num_matrix_pairs - 2 regular constraints
			 *	(one for each MatrixPair, excluding the identity and the
			 *	MatrixPair used to define the objective function),
			 *	preceded by three constraints which limit the step size
			 *	to MAX_STEP_SIZE.
			 */
			num_constraints = (num_matrix_pairs - 2) + 3;
			constraints = NEW_ARRAY(num_constraints, Constraint);

			/*
			 *	Set up the three step size constraints.
			 */
			step_size_constraints(constraints, objective_function);

			/*
			 *	Set up the regular constraints.
			 */
			regular_constraints(constraints, gen_list, objective_function, &may_be_saddle_point);

			/*
			 *	If we're not near an apparent saddle point,
			 *	do the linear programming.
			 */
			if (may_be_saddle_point == FALSE)
				linear_programming(objective_function, num_constraints, constraints, solution);
			/*
			 *	Otherwise ask the user whether s/he would like
			 *	to continue on normally or stop here.
			 */
			else
			{
				switch (interactivity)
				{
					case Dirichlet_interactive:
						if (saddle_query_given == FALSE)
						{
							choice = uQuery(	saddle_message,
												num_saddle_responses,
												saddle_responses,
												saddle_default);
							saddle_query_given = TRUE;
						}
						else
							choice = 0;	/* continue on */
						break;

					case Dirichlet_stop_here:
						choice = 1;	/*  stop here  */
						break;

					case Dirichlet_keep_going:
						choice = 0;	/* continue on */
						break;
				}

				switch (choice)
				{
					case 0:
						/*
						 *	Continue on normally.
						 */
						linear_programming(objective_function, num_constraints, constraints, solution);
						break;

					case 1:
						/*
						 *	Stop here, set *basepoint_moved to FALSE
						 *	to force an exit from the loop, and look at
						 *	the Dirichlet domain.
						 */
						copy3(solution, zero_solution);
						*basepoint_moved = FALSE;
						break;
				}
			}

			/*
			 *	Free the Constraint array.
			 */
			my_free(constraints);
		}

		else
		{
			/*
			 *	The derivative of the objective function is zero.
			 *
			 *	Ask the user whether to use this basepoint, or move on in
			 *	search of a local maximum of the injectivity radius.
			 */
			switch (interactivity)
			{
				case Dirichlet_interactive:
					choice = uQuery(	zero_deriv_message,
										num_zero_deriv_responses,
										zero_deriv_responses,
										zero_deriv_default);
					break;

				case Dirichlet_stop_here:
					choice = 1;	/*  stop here  */
					break;

				case Dirichlet_keep_going:
					choice = 0;	/* continue on */
					break;
			}

			switch (choice)
			{
				case 0:
					/*
					 *	Displace the basepoint and continue on.
					 */
					copy3(solution, small_displacement);
					break;

				case 1:
					/*
					 *	We want to stay at this point, so set the solution
					 *	to (0, 0, 0), and set *basepoint_moved to FALSE
					 *	to force an exit from the loop.
					 */
					copy3(solution, zero_solution);
					*basepoint_moved = FALSE;
					break;
			}
		}

		/*
		 *	Use the solution to conjugate the MatrixPairs.
		 */
		conjugate_matrices(gen_list, solution);

		/*
		 *	Resort the gen_list according to increasing image height.
		 */
		sort_gen_list(gen_list, num_matrix_pairs);

		/*
		 *	How far was the basepoint moved this time?
		 */
		distance_moved = length3(solution);

		/*
		 *	What is the total distance we've moved the basepoint?
		 */
		total_distance_moved += distance_moved;

		/*
		 *	If the basepoint moved any meaningful distance,
		 *	set *basepoint_moved to TRUE.
		 */
		if (distance_moved > BASEPOINT_EPSILON)
		{
			*basepoint_moved = TRUE;
			/*
			 *	If we move too far from the original basepoint, we should
			 *	recompute the Dirichlet domain to get a fresh set of
			 *	group elements.  Otherwise we keep going.
			 */
			keep_going = (total_distance_moved < MAX_TOTAL_DISTANCE);
		}
		else
			keep_going = FALSE;

		/*
		 *	The preceding code works great when the constraints are
		 *	either in general position, or are given to moderately high
		 *	precision.  But for low precision, non general position
		 *	constraints (e.g. for an 8-component circular chain with no
		 *	twist), the algorithm can knock around forever making
		 *	changes on the order of 1e-9.  The following code lets the
		 *	algorithm terminate in those cases.
		 */
		if (prev_distance_moved < BIG_BASEPOINT_EPSILON
		 &&      distance_moved < BIG_BASEPOINT_EPSILON)
		{
			/*
			 *	For sure we don't want to keep going after making
			 *	two fairly small changes in a row.
			 */
			keep_going = FALSE;
			/*
			 *	If the total_distance_moved is less than BIG_BASEPOINT_EPSILON,
			 *	then we want to set *basepoint_moved to FALSE to prevent
			 *	recomputation of the Dirichlet domain.  Note that we still
			 *	allow the possibility that *basepoint_moved is TRUE even when
			 *	the total_distance_moved is greater than BIG_BASEPOINT_EPSILON,
			 *	as could happen if preceding code artificially set *basepoint_moved
			 *	to FALSE to force an exit from the loop.
			 */
			if (total_distance_moved < BIG_BASEPOINT_EPSILON)
				*basepoint_moved = FALSE;
		}
		prev_distance_moved = distance_moved;

	} while (keep_going == TRUE);
}
Example #19
0
static void step_size_constraints(
	Constraint			*constraints,
	ObjectiveFunction	objective_function)
{
	int		i,
			j,
			i0;
	double	v[3][3],
			w[3][3],
			max_abs,
			length;

	/*
	 *	The three step size constraints will be faces of a cube,
	 *	with the vector for the objective_function pointing in the
	 *	direction of the cube's corner where the three faces intersect.
	 */

	/*
	 *	First find an orthonormal basis {v[0], v[1], v[2]} with
	 *	v[0] equal to the vector part of the objective function.
	 */

	/*
	 *	Let v[0] be the vector part of the objective function,
	 *	normalized to have length one.  (Elsewhere we checked that
	 *	its length is at least DERIVATIVE_EPSILON.)
	 */
	length = length3(objective_function);
	for (i = 0; i < 3; i++)
		v[0][i] = objective_function[i] / length;

	/*
	 *	Let v[1] be a unit vector orthogonal to v[0].
	 */

	/*
	 *	Let i0 be the index of the component of v[0] which has the greatest
	 *	absolute value.  (In particular, its absolute value is sure to be
	 *	nonzero.)
	 */
	max_abs = 0.0;
	for (i = 0; i < 3; i++)
		if (fabs(v[0][i]) > max_abs)
		{
			i0 = i;
			max_abs = fabs(v[0][i]);
		}

	/*
	 *	Write down a nonzero v[1] orthogonal to v[0] . . .
	 */
	v[1][i0]		= -v[0][(i0+1)%3] / v[0][i0];
	v[1][(i0+1)%3]	= 1.0;
	v[1][(i0+2)%3]	= 0.0;

	/*
	 *	. . . and normalize its length to 1.0.
	 */
	length = length3(v[1]);
	for (i = 0; i < 3; i++)
		v[1][i] /= length;

	/*
	 *	Let v[2] = v[0] x v[1].
	 */
	for (i = 0; i < 3; i++)
		v[2][i] = v[0][(i+1)%3] * v[1][(i+2)%3]  -  v[0][(i+2)%3] * v[1][(i+1)%3];

	/*
	 *	Use the orthonormal basis {v[0], v[1], v[2]} to find another basis
	 *	{w[0], w[1], w[2]} whose elements symmetrically surround v[0].
	 *
	 *		w[0] = v[0] + v[1]
	 *		w[1] = v[0] + ( -1/2 v[1]  +  sqrt(3)/2 v[2] )
	 *		w[2] = v[0] + ( -1/2 v[1]  -  sqrt(3)/2 v[2] )
	 */
	for (j = 0; j < 3; j++)
	{
		w[0][j] = v[0][j] + v[1][j];
		w[1][j] = v[0][j] + (-0.5*v[1][j] + ROOT3OVER2*v[2][j]);
		w[2][j] = v[0][j] + (-0.5*v[1][j] - ROOT3OVER2*v[2][j]);
	}

	/*
	 *	Use the basis {w[0], w[1], w[2]} to write down
	 *	the three step size constraints.
	 *
	 *	Technical note:  If you move in the direction of the objective
	 *	function vector v[0], the three constraints will be exactly
	 *	satisfied at a distance MAX_STEP_SIZE from the origin.  That is, the
	 *	inner product of (MAX_STEP_SIZE, 0, 0) with with each of (1, 1, 0),
	 *	(1, -1/2, sqrt(3)/2) and (1, -1/2, -sqrt(3)/2) is exactly
	 *	MAX_STEP_SIZE.  However, if you move to the side (orthogonally to
	 *	v[0]) it's possible to move a distance 2*MAX_STEP_SIZE.  E.g. the
	 *	inner product of (0, -2*MAX_STEP_SIZE, 0) with with each of
	 *	(1, 1, 0), (1, -1/2, sqrt(3)/2) and (1, -1/2, -sqrt(3)/2) is
	 *	-2*MAX_STEP_SIZE, MAX_STEP_SIZE and MAX_STEP_SIZE, respectively, so
	 *	it satisfies all three constraints.  But typically we won't be
	 *	moving to the side, and in any case all we really care about anyhow
	 *	is the order of magnitude of MAX_STEP_SIZE.  A factor of two isn't
	 *	important.
	 */
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 3; j++)
			constraints[i][j] = w[i][j];
		constraints[i][3] = -MAX_STEP_SIZE;
	}
}
Example #20
0
inline void normalized3(vec3 * r, vec3 v) {
	scalar l = length3( v );
	div3( r, v, l );
}