# Copyright (C) 2010 Jelmer Ypma. All Rights Reserved. # This code is published under the Eclipse Public License. # # File: is.ipoptr.R # Author: Jelmer Ypma # Date: 18 April 2010 # # Input: object # Output: bool telling whether the object is an ipoptr or not # # Changelog: # 09/03/2012: Removed ipoptr_environment because this caused a bug in combination with # data.table and it wasn't useful (thanks to Florian Oswald for reporting) is.ipoptr <- function(x) { # Check whether the object exists and is a list if( is.null(x) ) { return( FALSE ) } if( !is.list(x) ) { return( FALSE ) } # Define local flag defining whether we approximate the Hessian or not flag_hessian_approximation = FALSE if ( !is.null( x$options$string$hessian_approximation ) ) { flag_hessian_approximation = ( x$options$string$hessian_approximation == "limited-memory" ) } # Check whether the needed functions are supplied stopifnot( is.function(x$eval_f) ) stopifnot( is.function(x$eval_grad_f) ) stopifnot( is.function(x$eval_g) ) stopifnot( is.function(x$eval_jac_g) ) if ( !flag_hessian_approximation ) { stopifnot( is.function(x$eval_h) ) } # Check whether bounds are defined for all controls stopifnot( length( x$x0 ) == length( x$lower_bounds ) ) stopifnot( length( x$x0 ) == length( x$upper_bounds ) ) # Check whether the initial value is within the bounds stopifnot( all( x$x0 >= x$lower_bounds ) ) stopifnot( all( x$x0 <= x$upper_bounds ) ) num.controls <- length( x$x0 ) num.constraints <- length( x$constraint_lower_bounds ) # Check the length of some return values stopifnot( length(x$eval_f( x$x0 ))==1 ) stopifnot( length(x$eval_grad_f( x$x0 ))==num.controls ) stopifnot( length(x$eval_g( x$x0 ))==num.constraints ) stopifnot( length(x$eval_jac_g( x$x0 ))==length(unlist(x$eval_jac_g_structure)) ) # the number of non-zero elements in the Jacobian if ( !flag_hessian_approximation ) { stopifnot( length(x$eval_h( x$x0, 1, rep(1,num.constraints) ))==length(unlist(x$eval_h_structure)) ) # the number of non-zero elements in the Hessian } # Check the whether we don't have NA's in initial values stopifnot( all(!is.na(x$eval_f( x$x0 ))) ) stopifnot( all(!is.na(x$eval_grad_f( x$x0 ))) ) stopifnot( all(!is.na(x$eval_g( x$x0 ))) ) stopifnot( all(!is.na(x$eval_jac_g( x$x0 ))) ) # the number of non-zero elements in the Jacobian if ( !flag_hessian_approximation ) { stopifnot( all(!is.na(x$eval_h( x$x0, 1, rep(1,num.constraints) ))) ) # the number of non-zero elements in the Hessian } # Check whether a correct structure was supplied, and check the size stopifnot( is.list(x$eval_jac_g_structure) ) stopifnot( length(x$eval_jac_g_structure)==num.constraints ) if ( !flag_hessian_approximation ) { stopifnot( length(x$eval_h_structure)==num.controls ) stopifnot( is.list(x$eval_h_structure) ) } # Check the number of non-linear constraints stopifnot( length(x$constraint_lower_bounds)==length(x$constraint_upper_bounds) ) # Check whether none of the non-zero indices are larger than the number of controls # Also, the smallest index should be bigger than 0 if ( length( x$eval_jac_g_structure ) > 0 ) { stopifnot( max(unlist(x$eval_jac_g_structure)) <= num.controls ) stopifnot( min(unlist(x$eval_jac_g_structure)) > 0 ) } if ( !flag_hessian_approximation ) { stopifnot( max(unlist(x$eval_h_structure)) <= num.controls ) stopifnot( min(unlist(x$eval_h_structure)) > 0 ) } # Check whether option to approximate hessian and eval_h are both set # If we approximate the hessian, then we don't want to set eval_h if ( flag_hessian_approximation ) { if( !is.null( x$eval_h ) ) { warning("Option supplied to approximate hessian, but eval_h is defined.\nSolution: remove option hessian_approximation=limited-memory to use analytic derivatives.") } if( !is.null( x$eval_h_structure ) ) { warning("Option supplied to approximate hessian, but eval_h_structure is defined.\nSolution: remove option hessian_approximation=limited-memory to use analytic derivatives.") } } return( TRUE ) }