Beispiel #1
0
void NLPDakota::imp_calc_point(
	ERequiredFunc                required
	,const DVectorSlice           &x_full
	,bool                        newx
	,const ZeroOrderInfoSerial   *zero_order_info
	,const ObjGradInfoSerial     *obj_grad_info
	,const FirstOrderExplInfo    *first_order_expl_info
	) const
{
	using LinAlgOpPack::Vp_StV;
	typedef FirstOrderExplInfo::val_t     G_val_t;
	typedef FirstOrderExplInfo::ivect_t   G_ivect_t;
	typedef FirstOrderExplInfo::jvect_t   G_jvect_t;

	Cout << "\nEntering NLPDakota::imp_calc_point(...) ...\n";

//	throw std::logic_error("NLPDakota::imp_calc_point(): End, dam it!");

	if( newx ) {
		f_orig_updated_ = false;
		c_orig_updated_ = false;
		h_orig_updated_ = false;
		Gf_orig_updated_ = false;
		Gc_orig_updated_ = false;
		Gh_orig_updated_ = false;
		my_vec_view(dakota_functions_) = 0.0;
	}

	const DVectorSlice x_orig = x_full(1,n_orig_);

	//
	// Determine which quantities to compute
	//

	const bool calc_f  = ( required==CALC_F  || multi_calc_ )                                      && !f_orig_updated_;
	const bool calc_c  = ( required==CALC_C  || multi_calc_ )                                      && !c_orig_updated_;
	const bool calc_h  = ( required==CALC_H  || multi_calc_ )                                      && !h_orig_updated_;
	const bool calc_Gf = ( required==CALC_GF || ( (int)required >= (int)CALC_GF && multi_calc_ ) ) && !Gf_orig_updated_;
	const bool calc_Gc = ( required==CALC_GC || ( (int)required >= (int)CALC_GF && multi_calc_ ) ) && !Gc_orig_updated_;
	const bool calc_Gh = ( required==CALC_GH || ( (int)required >= (int)CALC_GF && multi_calc_ ) ) && !Gh_orig_updated_;

	if( !calc_f && !calc_c && !calc_h && !calc_Gf && !calc_Gc && !calc_Gh )
		return; // Everything is already computed at this point!

	value_type      *f         = NULL;
	DVector         *c         = NULL;
	DVector         *h         = NULL;
	DVector         *Gf        = NULL;
	G_val_t         *Gc_val    = NULL;
	G_ivect_t       *Gc_ivect  = NULL;
	G_jvect_t       *Gc_jvect  = NULL;
	G_val_t         *Gh_val    = NULL;
	G_ivect_t       *Gh_ivect  = NULL;
	G_jvect_t       *Gh_jvect  = NULL;

	if(zero_order_info) {
		if(calc_f) f = zero_order_info->f;
		if(calc_c) c = zero_order_info->c;
		if(calc_h) h = zero_order_info->h;
	}
	else if(obj_grad_info) {
		if(calc_f)  f  = obj_grad_info->f;
		if(calc_c)  c  = obj_grad_info->c;
		if(calc_h)  h  = obj_grad_info->h;
		if(calc_Gf) Gf = obj_grad_info->Gf;
	}
	else if(first_order_expl_info) {
		if(calc_f)  f  = first_order_expl_info->f;
		if(calc_c)  c  = first_order_expl_info->c;
		if(calc_h)  h  = first_order_expl_info->h;
		if(calc_Gf) Gf = first_order_expl_info->Gf;
		if(calc_Gc) {
			Gc_val   = first_order_expl_info->Gc_val;
			Gc_ivect = first_order_expl_info->Gc_ivect;
			Gc_jvect = first_order_expl_info->Gc_jvect;
		}
		if(calc_Gh) {
			Gh_val   = first_order_expl_info->Gh_val;
			Gh_ivect = first_order_expl_info->Gh_ivect;
			Gh_jvect = first_order_expl_info->Gh_jvect;
		}
	}
	else {
		THROW_EXCEPTION(
			!(zero_order_info || obj_grad_info || first_order_expl_info), std::logic_error
			,"NLPDakota::imp_calc_point(): Error!"
			);
	}

	//
	// Set the Dakota active-set vector.
	//
	// Dakota sorts the responce functions as general inequalities first
	// and general equalities second.
	//

	std::fill_n( &dakota_asv_[0], dakota_asv_.length(), 0 );

	const int num_obj_funcs = multi_obj_weights_.length();

	if( calc_f || calc_Gf ) {
		std::fill_n(
			&dakota_asv_[0], num_obj_funcs
			,(calc_f  ? 1 : 0) + (calc_Gf ? 2 : 0)
			);
	}
	if( ( calc_c || calc_Gc ) && num_nonlin_eq_ ) {
		std::fill_n(
			&dakota_asv_[num_obj_funcs + num_nonlin_ineq_], num_nonlin_eq_
			,(calc_c  ? 1 : 0) + (calc_Gc ? 2 : 0)
			);
	}
	if( ( calc_h || calc_Gh ) && num_nonlin_ineq_ ) {
		std::fill_n(
			&dakota_asv_[num_obj_funcs], num_nonlin_ineq_
			,(calc_h  ? 1 : 0) + (calc_Gh ? 2 : 0)
			);
	}

	//
	// Compute the nonlinear functions
	//

	my_vec_view(dakota_x_) = x_orig;
	model_->continuous_variables(dakota_x_);
	model_->compute_response(dakota_asv_);
	const Dakota::Response&   local_response           = model_->current_response();
	const Dakota::RealVector& local_function_values    = local_response.function_values();
	const Dakota::RealMatrix& local_function_gradients = local_response.function_gradients();

	// Look for failed response
	const bool eval_failed =  (local_function_values[0] == dakota_failed_value_);

	//
	// Map to the NLP objects
	//

	if(!eval_failed) {

		//
		// The evaluation succeeded so copy the values
		//

		// f, Gf
		if(calc_f)  *f  = 0.0;
		if(calc_Gf) *Gf = 0.0;
		for( int i = 0; i < num_obj_funcs; ++i ) {
			if(calc_f) {
				*f  += multi_obj_weights_[i] * local_function_values[i];
				dakota_functions_[i] = local_function_values[i]; // Save in dakota_functions
			}
			if(calc_Gf) {
				Vp_StV(
					&(*Gf)(1,n_orig_), multi_obj_weights_[i]
					,DVectorSlice(&const_cast<Dakota::RealMatrix&>(local_function_gradients)[i][0],n_orig_)
					);
			}
		}
		if(calc_Gf && Gf->dim() > n_orig_ )
			(*Gf)(n_orig_+1,Gf->dim()) = 0.0; // Zero for slack variables
		
		// c = [ A_lin_eq' * x - lin_eq_targ                                                                  ]
		//     [ response(num_obj_funcs+num_nonlin_ineq+1:num_obj_funs+num_nonlin_ineq+num_nonlin_eq) - nonlin_eq_targ ]
		if( calc_c ) {
			if( num_lin_eq_ ) {
				DVectorSlice c_lin = (*c)(1,num_lin_eq_);
				V_mV( &c_lin, my_vec_view(dakota_rsqp_opt_->lin_eq_targ()) );
				const Dakota::RealMatrix  &lin_eq_jac = dakota_rsqp_opt_->lin_eq_jac();
				for( int j = 0; j < num_lin_eq_; ++j ) {
					for( int i = 0; i < n_orig_; ++i ) {
						c_lin[j] += lin_eq_jac[j][i] * x_orig[i];
					}
				}
			}
			if( num_nonlin_eq_ ) {
				const value_type
					*nonlin_eq_ptr = &const_cast<Dakota::RealVector&>(local_function_values)[num_obj_funcs+num_nonlin_ineq_];
				V_VmV(
					&(*c)(num_lin_eq_+1,num_lin_eq_+num_nonlin_eq_)
					,DVectorSlice(const_cast<value_type*>(nonlin_eq_ptr),num_nonlin_eq_)
					,my_vec_view(dakota_rsqp_opt_->nonlin_eq_targ())
					);
				// Save in dakota_functions
				std::copy( nonlin_eq_ptr, nonlin_eq_ptr + num_nonlin_eq_, &dakota_functions_[num_obj_funcs+num_nonlin_ineq_] );
			}
		}
		
		// h = [ A_lin_ineq' * x                                   ]
		//     [ response(num_obj_funcs+1:num_obj_funs+num_lin_eq) ]
		if( calc_h ) {
			//
			if( num_lin_ineq_ ) {
				DVectorSlice h_lin = (*h)(1,num_lin_ineq_);
				const Dakota::RealMatrix  &lin_ineq_jac = dakota_rsqp_opt_->lin_ineq_jac();
				for( int j = 0; j < num_lin_ineq_; ++j ) {
					for( int i = 0; i < n_orig_; ++i ) {
						h_lin[j] += lin_ineq_jac[j][i] * x_orig[i];
					}
				}
			}
			//
			if( num_nonlin_ineq_ ) {
				const value_type
					*nonlin_ineq_ptr = &const_cast<Dakota::RealVector&>(local_function_values)[num_obj_funcs];
				(*h)(num_lin_ineq_+1,num_lin_ineq_+num_nonlin_ineq_)
					= DVectorSlice(const_cast<value_type*>(nonlin_ineq_ptr),num_nonlin_ineq_);
				// Save in dakota_functions
				std::copy( nonlin_ineq_ptr, nonlin_ineq_ptr + num_nonlin_ineq_, &dakota_functions_[num_obj_funcs] );
			}
		}
		
		// Gc = [ A_lin_eq'                                     ]
		//      [ response.grad[num_nonlin_ineq+1]'             ]
		//      [ ..                                            ]
		//      [ response.grad[num_nonlin_ineq+num_nonlin_eq]' ]
		if( calc_Gc ) {
			index_type nz = 0;
			if( num_lin_eq_ ) {
				const Dakota::RealMatrix  &lin_eq_jac = dakota_rsqp_opt_->lin_eq_jac();
				for( int j = 1; j <= num_lin_eq_; ++j ) {
					for( int i = 1; i <= n_orig_; ++i ) {
						(*Gc_val)[nz]   = lin_eq_jac[j-1][i-1];
						(*Gc_ivect)[nz] = i;
						(*Gc_jvect)[nz] = j;
						++nz;
					}
				}
			}
			if( num_nonlin_eq_ ) {
				for( int j = 1; j <= num_nonlin_eq_; ++j ) {
					for( int i = 1; i <= n_orig_; ++i ) {
						(*Gc_val)[nz]   = local_function_gradients[num_obj_funcs+num_nonlin_ineq_+j-1][i-1];
						(*Gc_ivect)[nz] = i;
						(*Gc_jvect)[nz] = j + num_lin_eq_;
						++nz;
					}
				}
			}
		}
		
		// Gh = [ A_lin_ineq'                   ]
		//      [ response.grad[1]'             ]
		//      [ ..                            ]
		//      [ response.grad[num_nonlin_eq]' ]
		if( calc_Gh ) {
			index_type nz = 0;
			if( num_lin_ineq_ ) {
				const Dakota::RealMatrix  &lin_ineq_jac = dakota_rsqp_opt_->lin_ineq_jac();
				for( int j = 1; j <= num_lin_ineq_; ++j ) {
					for( int i = 1; i <= n_orig_; ++i ) {
						(*Gh_val)[nz]   = lin_ineq_jac[j-1][i-1];
						(*Gh_ivect)[nz] = i;
						(*Gh_jvect)[nz] = j;
						++nz;
					}
				}
			}
			if( num_nonlin_ineq_ ) {
				for( int j = 1; j <= num_nonlin_ineq_; ++j ) {
					for( int i = 1; i <= n_orig_; ++i ) {
						(*Gh_val)[nz]   = local_function_gradients[num_obj_funcs+j-1][i-1];
						(*Gh_ivect)[nz] = i;
						(*Gh_jvect)[nz] = j;
						++nz;
					}
				}
			}
		}
	}
	else {
		//
		// The evaluation failed so just fill everything with
		// and invalid number that will trigger a back tracking
		//

		// f, Gf
		if(calc_f)  *f  = invalid_func_value_;
		if(calc_Gf) *Gf = invalid_func_value_;
		// c
		if(calc_c)  *c = invalid_func_value_;
		// h
		if(calc_h) *h = invalid_func_value_;
		// Gc
		if(calc_Gc) {
			index_type nz = 0;
			for( int j = 1; j <= m_orig_; ++j ) {
				for( int i = 1; i <= n_orig_; ++i ) {
					(*Gc_val)[nz]   = invalid_func_value_;
					(*Gc_ivect)[nz] = i;
					(*Gc_jvect)[nz] = j;
					++nz;
				}
			}
		}
		// Gh
		if( calc_Gh ) {
			index_type nz = 0;
			for( int j = 1; j <= mI_orig_; ++j ) {
				for( int i = 1; i <= n_orig_; ++i ) {
					(*Gh_val)[nz]   = invalid_func_value_;
					(*Gh_ivect)[nz] = i;
					(*Gh_jvect)[nz] = j;
					++nz;
				}
			}
		}

	}

	if(calc_f)   f_orig_updated_  = true;
	if(calc_c)   c_orig_updated_  = true;
	if(calc_h)   h_orig_updated_  = true;
	if(calc_Gf)  Gf_orig_updated_ = true;
	if(calc_Gc)  Gc_orig_updated_ = true;
	if(calc_Gh)  Gh_orig_updated_ = true;

}