|  | @@ -224,6 +224,28 @@ void SummarizeReducedProgram(const Program& program, Solver::Summary* summary) {
 | 
	
		
			
				|  |  |    summary->num_residuals_reduced = program.NumResiduals();
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +bool ParameterBlocksAreFinite(const ProblemImpl* problem,
 | 
	
		
			
				|  |  | +                              string* message) {
 | 
	
		
			
				|  |  | +  CHECK_NOTNULL(message);
 | 
	
		
			
				|  |  | +  const Program& program = problem->program();
 | 
	
		
			
				|  |  | +  const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
 | 
	
		
			
				|  |  | +  for (int i = 0; i < parameter_blocks.size(); ++i) {
 | 
	
		
			
				|  |  | +    const double* array = parameter_blocks[i]->user_state();
 | 
	
		
			
				|  |  | +    const int size = parameter_blocks[i]->Size();
 | 
	
		
			
				|  |  | +    const int invalid_index = FindInvalidValue(size, array);
 | 
	
		
			
				|  |  | +    if (invalid_index != size) {
 | 
	
		
			
				|  |  | +      *message = StringPrintf(
 | 
	
		
			
				|  |  | +          "ParameterBlock: %p with size %d has at least one invalid value.\n"
 | 
	
		
			
				|  |  | +          "First invalid value is at index: %d.\n"
 | 
	
		
			
				|  |  | +          "Parameter block values: ",
 | 
	
		
			
				|  |  | +          array, size, invalid_index);
 | 
	
		
			
				|  |  | +      AppendArrayToString(size, array, message);
 | 
	
		
			
				|  |  | +      return false;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return true;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  bool LineSearchOptionsAreValid(const Solver::Options& options,
 | 
	
		
			
				|  |  |                                 string* message) {
 | 
	
		
			
				|  |  |    // Validate values for configuration parameters supplied by user.
 | 
	
	
		
			
				|  | @@ -419,7 +441,7 @@ void SolverImpl::Solve(const Solver::Options& options,
 | 
	
		
			
				|  |  |            << " residual blocks, "
 | 
	
		
			
				|  |  |            << problem_impl->NumResiduals()
 | 
	
		
			
				|  |  |            << " residuals.";
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +  *CHECK_NOTNULL(summary) = Solver::Summary();
 | 
	
		
			
				|  |  |    if (options.minimizer_type == TRUST_REGION) {
 | 
	
		
			
				|  |  |      TrustRegionSolve(options, problem_impl, summary);
 | 
	
		
			
				|  |  |    } else {
 | 
	
	
		
			
				|  | @@ -440,9 +462,6 @@ void SolverImpl::TrustRegionSolve(const Solver::Options& original_options,
 | 
	
		
			
				|  |  |    Program* original_program = original_problem_impl->mutable_program();
 | 
	
		
			
				|  |  |    ProblemImpl* problem_impl = original_problem_impl;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  // Reset the summary object to its default values.
 | 
	
		
			
				|  |  | -  *CHECK_NOTNULL(summary) = Solver::Summary();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    summary->minimizer_type = TRUST_REGION;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    SummarizeGivenProgram(*original_program, summary);
 | 
	
	
		
			
				|  | @@ -484,6 +503,11 @@ void SolverImpl::TrustRegionSolve(const Solver::Options& original_options,
 | 
	
		
			
				|  |  |      return;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  if (!ParameterBlocksAreFinite(problem_impl, &summary->message)) {
 | 
	
		
			
				|  |  | +    LOG(ERROR) << "Terminating: " << summary->message;
 | 
	
		
			
				|  |  | +    return;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    event_logger.AddEvent("Init");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    original_program->SetParameterBlockStatePtrsToUserStatePtrs();
 | 
	
	
		
			
				|  | @@ -704,9 +728,6 @@ void SolverImpl::LineSearchSolve(const Solver::Options& original_options,
 | 
	
		
			
				|  |  |    Program* original_program = original_problem_impl->mutable_program();
 | 
	
		
			
				|  |  |    ProblemImpl* problem_impl = original_problem_impl;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  // Reset the summary object to its default values.
 | 
	
		
			
				|  |  | -  *CHECK_NOTNULL(summary) = Solver::Summary();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    SummarizeGivenProgram(*original_program, summary);
 | 
	
		
			
				|  |  |    summary->minimizer_type = LINE_SEARCH;
 | 
	
		
			
				|  |  |    summary->line_search_direction_type =
 | 
	
	
		
			
				|  | @@ -746,6 +767,11 @@ void SolverImpl::LineSearchSolve(const Solver::Options& original_options,
 | 
	
		
			
				|  |  |    summary->num_threads_given = original_options.num_threads;
 | 
	
		
			
				|  |  |    summary->num_threads_used = options.num_threads;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  if (!ParameterBlocksAreFinite(problem_impl, &summary->message)) {
 | 
	
		
			
				|  |  | +    LOG(ERROR) << "Terminating: " << summary->message;
 | 
	
		
			
				|  |  | +    return;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    if (original_options.linear_solver_ordering != NULL) {
 | 
	
		
			
				|  |  |      if (!IsOrderingValid(original_options, problem_impl, &summary->message)) {
 | 
	
		
			
				|  |  |        LOG(ERROR) << summary->message;
 |