File: fnchk.R

package info (click to toggle)
r-cran-optimx 2022-4.30%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,524 kB
  • sloc: sh: 21; makefile: 5
file content (138 lines) | stat: -rw-r--r-- 4,548 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
fnchk <- function(xpar, ffn, trace=0, ... ) {
# fnchk <- function(xpar, ffn, cctrl=list(trace=0), ... )
#  A function to check the nonlinear optimization file that is "ffn", with gradient gr
#  The intention is to automatically test the gradient, hessian, Jacobian, Jacobian second derivatives,
#    as well as bounds
#
#  This function can take-in multiple starting values
#
# Input:
#  xpar = a vector of starting values (may be scaled)
#  ffn = objective function (assumed to be sufficiently differentiable). May be created by setup program.
#  cctrl = a list of control information FOR THE CHECKING PROGRAM. See Details.
#          The name has been changed from control to avoid confusion with control list in optim/optimx
#  ...     = other arguments to the function identified by fname
#
#  NOTE: bounds do NOT appear here.
#
# Output:
#      fval
#      infeasible
#      excode
#      msg
#
#  Author:  John Nash
#  Date: Sept 18, 2011, mod July 2015
#################################################################
  maxard10<-function(one, two) { 
  # get max abs relative difference scaled by 10.0 in denominator
  # This internal function is used to make comparisons using a 
  # relative difference, but avoiding zero divide
    result<-max(abs((one-two)/(abs(one)+abs(two)+10.0)))
    return(result)
  }
#########
   if (trace > 2) {
      cat("fnchk: ffn =\n")
      print(ffn)
      cat("fnchk: xpar:")
      print(xpar)
      cat("fnchk: dots:")
      print(list(...))
   }
   infeasible<-FALSE # set value OK, then alter if not feasible later
   excode <- 0 # ditto
   msg <- "fnchk OK" # ditto
   if (trace > 1) {
      cat("about to call ffn(xpar, ...)\n")
      cat("ffn:")
      print(ffn)
      cat("xpar & dots:")
      print(xpar)
      print(list(...))
   }
   test<-try(fval<-ffn(xpar, ...)) # !! KEY LINE
   if (trace > 1) {
      cat("test in fnchk:")
      print(test)
   }
   # Note: This incurs one EXTRA function evaluation because optimx wraps other methods
   if (inherits(test, "try-error") ) {
      fval<-NA
      attr(fval, "inadmissible")<-TRUE
   }
   if (trace > 0) {
      cat("Function value at supplied parameters =")
      print(fval) # Use "print" rather than "cat" to allow extra structure to be displayed
      print(str(fval))
      print(is.vector(fval))
   }
   if (!is.null(attr(fval,"inadmissible")) && (attr(fval, "inadmissible"))) {
      infeasible <- TRUE
      excode <- -1
      msg <- "Function evaluation returns INADMISSIBLE"
      if (trace > 0) cat(msg,"\n")
   }

   # Also check that it is returned as a scalar
   if (is.vector(fval)) {
      if (length(fval)>1) { # added 120411
        excode <- -4
        msg <- "Function evaluation returns a vector not a scalar"
        fval <- NA # and force to NA to control possible later actions
        infeasible <- TRUE
        if (trace > 0) cat(msg,"\n")
      }
   }

   if (is.list(fval)) {
      excode <- -4
      msg <- "Function evaluation returns a list not a scalar"
        fval <- NA # and force to NA to control possible later actions
      infeasible <- TRUE
      if (trace > 0) cat(msg,"\n")
   }

   if (is.matrix(fval)) {
      excode <- -4
      msg <- "Function evaluation returns a matrix list not a scalar"
      fval <- NA # and force to NA to control possible later actions
      infeasible <- TRUE
      if (trace > 0) cat(msg,"\n")
   }

   if (is.array(fval)) {
      excode <- -4
      msg <- "Function evaluation returns an array not a scalar"
      fval <- NA # and force to NA to control possible later actions
      infeasible <- TRUE
      if (trace > 0) cat(msg,"\n")
   }

   if ((length(fval)!=1) && !(is.vector(fval))) { #this may never get executed
      excode <- -4
      msg <- "Function returned not length 1, despite not vector, matrix or array"
      fval <- NA # and force to NA to control possible later actions
      infeasible <- TRUE
      if (trace > 0) cat(msg,"\n")
   }

   if ( ! (is.numeric(fval)) ) {
      excode <- -1 
      msg <- "Function evaluation returned non-numeric value"
      fval <- NA # and force to NA to control possible later actions
      infeasible <- TRUE
      if (trace > 0) cat(msg,"\n")
   }

   if (is.infinite(fval) || is.na(fval)) {
      excode <- -1 
      msg <- "Function evaluation returned Inf or NA (non-computable)"
      infeasible <- TRUE
      if (trace > 0) cat(msg,"\n")
   }
   if (trace > 0) cat("Function at given point=",fval,"\n")
   answer <- list(fval=fval, infeasible=infeasible, excode=excode, msg=msg)
}
### end of fnchk ***