docs: public boolean refine(List<CameraPinhole> calibration , DMatrix4x4 Q ) {
  		if( calibration.size() != cameras.size )
  			throw new RuntimeException("Calibration and cameras do not match");
  
  		computeNumberOfCalibrationParameters();
  		func = new ResidualK();
  
  		if( func.getNumOfInputsN() > 6*calibration.size() )
  			throw new IllegalArgumentException("Need more views to refine. eqs="+(3*calibration.size()+" unknowns="+func.getNumOfInputsN()));
  
  		// Declared new each time to ensure all variables are properly zeroed
  
  
  		// plane at infinity to the null space of Q
  		ConvertDMatrixStruct.convert(Q,_Q);
  		nullspace.process(_Q,1,p);
  		CommonOps_DDRM.divide(p,p.get(3));
  		p.numRows=3;
  
  		// Convert input objects into an array which can be understood by optimization
  		encode(calibration,p,param);
  
  		// Configure optimization
  //		optimizer.setVerbose(System.out,0);
  		optimizer.setFunction(func,null); // Compute using a numerical Jacobian
  		optimizer.initialize(param.data,converge.ftol,converge.gtol);
  
  		// Tell it to run for at most 100 iterations
  		if( !UtilOptimize.process(optimizer,converge.maxIterations) )
  			return false;
  
  		// extract solution
  		decode(optimizer.getParameters(),calibration,p);
  		recomputeQ(p,Q);
  
  		return true;
  	}