351 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			351 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						|||
| 
								 | 
							
								Bullet Continuous Collision Detection and Physics Library
							 | 
						|||
| 
								 | 
							
								Copyright (c) 2003-2013 Erwin Coumans  http://bulletphysics.org
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								This software is provided 'as-is', without any express or implied warranty.
							 | 
						|||
| 
								 | 
							
								In no event will the authors be held liable for any damages arising from the use of this software.
							 | 
						|||
| 
								 | 
							
								Permission is granted to anyone to use this software for any purpose, 
							 | 
						|||
| 
								 | 
							
								including commercial applications, and to alter it and redistribute it freely, 
							 | 
						|||
| 
								 | 
							
								subject to the following restrictions:
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
							 | 
						|||
| 
								 | 
							
								2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
							 | 
						|||
| 
								 | 
							
								3. This notice may not be removed or altered from any source distribution.
							 | 
						|||
| 
								 | 
							
								*/
							 | 
						|||
| 
								 | 
							
								///original version written by Erwin Coumans, October 2013
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#ifndef BT_LEMKE_SOLVER_H
							 | 
						|||
| 
								 | 
							
								#define BT_LEMKE_SOLVER_H
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#include "btMLCPSolverInterface.h"
							 | 
						|||
| 
								 | 
							
								#include "btLemkeAlgorithm.h"
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								///The btLemkeSolver is based on "Fast Implementation of Lemke<6B>s Algorithm for Rigid Body Contact Simulation (John E. Lloyd) "
							 | 
						|||
| 
								 | 
							
								///It is a slower but more accurate solver. Increase the m_maxLoops for better convergence, at the cost of more CPU time.
							 | 
						|||
| 
								 | 
							
								///The original implementation of the btLemkeAlgorithm was done by Kilian Grundl from the MBSim team
							 | 
						|||
| 
								 | 
							
								class btLemkeSolver : public btMLCPSolverInterface
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								protected:
							 | 
						|||
| 
								 | 
							
									
							 | 
						|||
| 
								 | 
							
								public:
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									btScalar	m_maxValue;
							 | 
						|||
| 
								 | 
							
									int			m_debugLevel;
							 | 
						|||
| 
								 | 
							
									int			m_maxLoops;
							 | 
						|||
| 
								 | 
							
									bool		m_useLoHighBounds;
							 | 
						|||
| 
								 | 
							
									
							 | 
						|||
| 
								 | 
							
									
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									btLemkeSolver()
							 | 
						|||
| 
								 | 
							
										:m_maxValue(100000),
							 | 
						|||
| 
								 | 
							
										m_debugLevel(0),
							 | 
						|||
| 
								 | 
							
										m_maxLoops(1000),
							 | 
						|||
| 
								 | 
							
										m_useLoHighBounds(true)
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									virtual bool solveMLCP(const btMatrixXu & A, const btVectorXu & b, btVectorXu& x, const btVectorXu & lo,const btVectorXu & hi,const btAlignedObjectArray<int>& limitDependency, int numIterations, bool useSparsity = true)
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										if (m_useLoHighBounds)
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										BT_PROFILE("btLemkeSolver::solveMLCP");
							 | 
						|||
| 
								 | 
							
										int n = A.rows();
							 | 
						|||
| 
								 | 
							
										if (0==n)
							 | 
						|||
| 
								 | 
							
											return true;
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										bool fail = false;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										btVectorXu solution(n);
							 | 
						|||
| 
								 | 
							
										btVectorXu q1;
							 | 
						|||
| 
								 | 
							
										q1.resize(n);
							 | 
						|||
| 
								 | 
							
										for (int row=0;row<n;row++)
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											q1[row] = -b[row];
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									//		cout << "A" << endl;
							 | 
						|||
| 
								 | 
							
									//		cout << A << endl;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											/////////////////////////////////////
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											//slow matrix inversion, replace with LU decomposition
							 | 
						|||
| 
								 | 
							
											btMatrixXu A1;
							 | 
						|||
| 
								 | 
							
											btMatrixXu B(n,n);
							 | 
						|||
| 
								 | 
							
											{
							 | 
						|||
| 
								 | 
							
												BT_PROFILE("inverse(slow)");
							 | 
						|||
| 
								 | 
							
												A1.resize(A.rows(),A.cols());
							 | 
						|||
| 
								 | 
							
												for (int row=0;row<A.rows();row++)
							 | 
						|||
| 
								 | 
							
												{
							 | 
						|||
| 
								 | 
							
													for (int col=0;col<A.cols();col++)
							 | 
						|||
| 
								 | 
							
													{
							 | 
						|||
| 
								 | 
							
														A1.setElem(row,col,A(row,col));
							 | 
						|||
| 
								 | 
							
													}
							 | 
						|||
| 
								 | 
							
												}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
												btMatrixXu matrix;
							 | 
						|||
| 
								 | 
							
												matrix.resize(n,2*n);
							 | 
						|||
| 
								 | 
							
												for (int row=0;row<n;row++)
							 | 
						|||
| 
								 | 
							
												{
							 | 
						|||
| 
								 | 
							
													for (int col=0;col<n;col++)
							 | 
						|||
| 
								 | 
							
													{
							 | 
						|||
| 
								 | 
							
														matrix.setElem(row,col,A1(row,col));
							 | 
						|||
| 
								 | 
							
													}
							 | 
						|||
| 
								 | 
							
												}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
												btScalar ratio,a;
							 | 
						|||
| 
								 | 
							
												int i,j,k;
							 | 
						|||
| 
								 | 
							
												for(i = 0; i < n; i++){
							 | 
						|||
| 
								 | 
							
												for(j = n; j < 2*n; j++){
							 | 
						|||
| 
								 | 
							
													if(i==(j-n))
							 | 
						|||
| 
								 | 
							
														matrix.setElem(i,j,1.0);
							 | 
						|||
| 
								 | 
							
													else
							 | 
						|||
| 
								 | 
							
														matrix.setElem(i,j,0.0);
							 | 
						|||
| 
								 | 
							
												}
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
											for(i = 0; i < n; i++){
							 | 
						|||
| 
								 | 
							
												for(j = 0; j < n; j++){
							 | 
						|||
| 
								 | 
							
													if(i!=j)
							 | 
						|||
| 
								 | 
							
													{
							 | 
						|||
| 
								 | 
							
														btScalar v = matrix(i,i);
							 | 
						|||
| 
								 | 
							
														if (btFuzzyZero(v))
							 | 
						|||
| 
								 | 
							
														{
							 | 
						|||
| 
								 | 
							
															a = 0.000001f;
							 | 
						|||
| 
								 | 
							
														}
							 | 
						|||
| 
								 | 
							
														ratio = matrix(j,i)/matrix(i,i);
							 | 
						|||
| 
								 | 
							
														for(k = 0; k < 2*n; k++){
							 | 
						|||
| 
								 | 
							
															matrix.addElem(j,k,- ratio * matrix(i,k));
							 | 
						|||
| 
								 | 
							
														}
							 | 
						|||
| 
								 | 
							
													}
							 | 
						|||
| 
								 | 
							
												}
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
											for(i = 0; i < n; i++){
							 | 
						|||
| 
								 | 
							
												a = matrix(i,i);
							 | 
						|||
| 
								 | 
							
												if (btFuzzyZero(a))
							 | 
						|||
| 
								 | 
							
												{
							 | 
						|||
| 
								 | 
							
													a = 0.000001f;
							 | 
						|||
| 
								 | 
							
												}
							 | 
						|||
| 
								 | 
							
												btScalar invA = 1.f/a;
							 | 
						|||
| 
								 | 
							
												for(j = 0; j < 2*n; j++){
							 | 
						|||
| 
								 | 
							
													matrix.mulElem(i,j,invA);
							 | 
						|||
| 
								 | 
							
												}
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											for (int row=0;row<n;row++)
							 | 
						|||
| 
								 | 
							
												{
							 | 
						|||
| 
								 | 
							
													for (int col=0;col<n;col++)
							 | 
						|||
| 
								 | 
							
													{
							 | 
						|||
| 
								 | 
							
														B.setElem(row,col,matrix(row,n+col));
							 | 
						|||
| 
								 | 
							
													}
							 | 
						|||
| 
								 | 
							
												}
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										btMatrixXu b1(n,1);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										btMatrixXu M(n*2,n*2);
							 | 
						|||
| 
								 | 
							
										for (int row=0;row<n;row++)
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											b1.setElem(row,0,-b[row]);
							 | 
						|||
| 
								 | 
							
											for (int col=0;col<n;col++)
							 | 
						|||
| 
								 | 
							
											{
							 | 
						|||
| 
								 | 
							
												btScalar v =B(row,col);
							 | 
						|||
| 
								 | 
							
												M.setElem(row,col,v);
							 | 
						|||
| 
								 | 
							
												M.setElem(n+row,n+col,v);
							 | 
						|||
| 
								 | 
							
												M.setElem(n+row,col,-v);
							 | 
						|||
| 
								 | 
							
												M.setElem(row,n+col,-v);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										btMatrixXu Bb1 = B*b1;
							 | 
						|||
| 
								 | 
							
								//		q = [ (-B*b1 - lo)'   (hi + B*b1)' ]'
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										btVectorXu qq;
							 | 
						|||
| 
								 | 
							
										qq.resize(n*2);
							 | 
						|||
| 
								 | 
							
										for (int row=0;row<n;row++)
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											qq[row] = -Bb1(row,0)-lo[row];
							 | 
						|||
| 
								 | 
							
											qq[n+row] = Bb1(row,0)+hi[row];
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										btVectorXu z1;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										btMatrixXu y1;
							 | 
						|||
| 
								 | 
							
										y1.resize(n,1);
							 | 
						|||
| 
								 | 
							
										btLemkeAlgorithm lemke(M,qq,m_debugLevel);
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											BT_PROFILE("lemke.solve");
							 | 
						|||
| 
								 | 
							
											lemke.setSystem(M,qq);
							 | 
						|||
| 
								 | 
							
											z1  = lemke.solve(m_maxLoops);
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
										for (int row=0;row<n;row++)
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											y1.setElem(row,0,z1[2*n+row]-z1[3*n+row]);
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
										btMatrixXu y1_b1(n,1);
							 | 
						|||
| 
								 | 
							
										for (int i=0;i<n;i++)
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											y1_b1.setElem(i,0,y1(i,0)-b1(i,0));
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										btMatrixXu x1;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										x1 = B*(y1_b1);
							 | 
						|||
| 
								 | 
							
											
							 | 
						|||
| 
								 | 
							
										for (int row=0;row<n;row++)
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											solution[row] = x1(row,0);//n];
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										int errorIndexMax = -1;
							 | 
						|||
| 
								 | 
							
										int errorIndexMin = -1;
							 | 
						|||
| 
								 | 
							
										float errorValueMax = -1e30;
							 | 
						|||
| 
								 | 
							
										float errorValueMin = 1e30;
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										for (int i=0;i<n;i++)
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											x[i] = solution[i];
							 | 
						|||
| 
								 | 
							
											volatile btScalar check = x[i];
							 | 
						|||
| 
								 | 
							
											if (x[i] != check)
							 | 
						|||
| 
								 | 
							
											{
							 | 
						|||
| 
								 | 
							
												//printf("Lemke result is #NAN\n");
							 | 
						|||
| 
								 | 
							
												x.setZero();
							 | 
						|||
| 
								 | 
							
												return false;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
											
							 | 
						|||
| 
								 | 
							
											//this is some hack/safety mechanism, to discard invalid solutions from the Lemke solver 
							 | 
						|||
| 
								 | 
							
											//we need to figure out why it happens, and fix it, or detect it properly)
							 | 
						|||
| 
								 | 
							
											if (x[i]>m_maxValue)
							 | 
						|||
| 
								 | 
							
											{
							 | 
						|||
| 
								 | 
							
												if (x[i]> errorValueMax)
							 | 
						|||
| 
								 | 
							
												{
							 | 
						|||
| 
								 | 
							
													fail = true;
							 | 
						|||
| 
								 | 
							
													errorIndexMax = i;
							 | 
						|||
| 
								 | 
							
													errorValueMax = x[i];
							 | 
						|||
| 
								 | 
							
												}
							 | 
						|||
| 
								 | 
							
												////printf("x[i] = %f,",x[i]);
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
											if (x[i]<-m_maxValue)
							 | 
						|||
| 
								 | 
							
											{
							 | 
						|||
| 
								 | 
							
												if (x[i]<errorValueMin)
							 | 
						|||
| 
								 | 
							
												{
							 | 
						|||
| 
								 | 
							
													errorIndexMin = i;
							 | 
						|||
| 
								 | 
							
													errorValueMin = x[i];
							 | 
						|||
| 
								 | 
							
													fail = true;
							 | 
						|||
| 
								 | 
							
													//printf("x[i] = %f,",x[i]);
							 | 
						|||
| 
								 | 
							
												}
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
										if (fail)
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											int m_errorCountTimes = 0;
							 | 
						|||
| 
								 | 
							
											if (errorIndexMin<0)
							 | 
						|||
| 
								 | 
							
												errorValueMin = 0.f;
							 | 
						|||
| 
								 | 
							
											if (errorIndexMax<0)
							 | 
						|||
| 
								 | 
							
												errorValueMax = 0.f;
							 | 
						|||
| 
								 | 
							
											m_errorCountTimes++;
							 | 
						|||
| 
								 | 
							
										//	printf("Error (x[%d] = %f, x[%d] = %f), resetting %d times\n", errorIndexMin,errorValueMin, errorIndexMax, errorValueMax, errorCountTimes++);
							 | 
						|||
| 
								 | 
							
											for (int i=0;i<n;i++)
							 | 
						|||
| 
								 | 
							
											{
							 | 
						|||
| 
								 | 
							
												x[i]=0.f;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
										return !fail;
							 | 
						|||
| 
								 | 
							
									} else
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
											int dimension = A.rows();
							 | 
						|||
| 
								 | 
							
										if (0==dimension)
							 | 
						|||
| 
								 | 
							
											return true;
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
								//		printf("================ solving using Lemke/Newton/Fixpoint\n");
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										btVectorXu q;
							 | 
						|||
| 
								 | 
							
										q.resize(dimension);
							 | 
						|||
| 
								 | 
							
										for (int row=0;row<dimension;row++)
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											q[row] = -b[row];
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										btLemkeAlgorithm lemke(A,q,m_debugLevel);
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										lemke.setSystem(A,q);
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										btVectorXu solution = lemke.solve(m_maxLoops);
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										//check solution
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										bool fail = false;
							 | 
						|||
| 
								 | 
							
										int errorIndexMax = -1;
							 | 
						|||
| 
								 | 
							
										int errorIndexMin = -1;
							 | 
						|||
| 
								 | 
							
										float errorValueMax = -1e30;
							 | 
						|||
| 
								 | 
							
										float errorValueMin = 1e30;
							 | 
						|||
| 
								 | 
							
										
							 | 
						|||
| 
								 | 
							
										for (int i=0;i<dimension;i++)
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											x[i] = solution[i+dimension];
							 | 
						|||
| 
								 | 
							
											volatile btScalar check = x[i];
							 | 
						|||
| 
								 | 
							
											if (x[i] != check)
							 | 
						|||
| 
								 | 
							
											{
							 | 
						|||
| 
								 | 
							
												x.setZero();
							 | 
						|||
| 
								 | 
							
												return false;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
											
							 | 
						|||
| 
								 | 
							
											//this is some hack/safety mechanism, to discard invalid solutions from the Lemke solver 
							 | 
						|||
| 
								 | 
							
											//we need to figure out why it happens, and fix it, or detect it properly)
							 | 
						|||
| 
								 | 
							
											if (x[i]>m_maxValue)
							 | 
						|||
| 
								 | 
							
											{
							 | 
						|||
| 
								 | 
							
												if (x[i]> errorValueMax)
							 | 
						|||
| 
								 | 
							
												{
							 | 
						|||
| 
								 | 
							
													fail = true;
							 | 
						|||
| 
								 | 
							
													errorIndexMax = i;
							 | 
						|||
| 
								 | 
							
													errorValueMax = x[i];
							 | 
						|||
| 
								 | 
							
												}
							 | 
						|||
| 
								 | 
							
												////printf("x[i] = %f,",x[i]);
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
											if (x[i]<-m_maxValue)
							 | 
						|||
| 
								 | 
							
											{
							 | 
						|||
| 
								 | 
							
												if (x[i]<errorValueMin)
							 | 
						|||
| 
								 | 
							
												{
							 | 
						|||
| 
								 | 
							
													errorIndexMin = i;
							 | 
						|||
| 
								 | 
							
													errorValueMin = x[i];
							 | 
						|||
| 
								 | 
							
													fail = true;
							 | 
						|||
| 
								 | 
							
													//printf("x[i] = %f,",x[i]);
							 | 
						|||
| 
								 | 
							
												}
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
										if (fail)
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											static int errorCountTimes = 0;
							 | 
						|||
| 
								 | 
							
											if (errorIndexMin<0)
							 | 
						|||
| 
								 | 
							
												errorValueMin = 0.f;
							 | 
						|||
| 
								 | 
							
											if (errorIndexMax<0)
							 | 
						|||
| 
								 | 
							
												errorValueMax = 0.f;
							 | 
						|||
| 
								 | 
							
											printf("Error (x[%d] = %f, x[%d] = %f), resetting %d times\n", errorIndexMin,errorValueMin, errorIndexMax, errorValueMax, errorCountTimes++);
							 | 
						|||
| 
								 | 
							
											for (int i=0;i<dimension;i++)
							 | 
						|||
| 
								 | 
							
											{
							 | 
						|||
| 
								 | 
							
												x[i]=0.f;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										return !fail;
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									return true;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#endif //BT_LEMKE_SOLVER_H
							 |