Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • clear specified function for -optimize()-

    Hi -- I am using the -optimize()- utility in -mata-, and, there, you have to specify the function used to evaluate f(p). Specifically, you name this function as the second argument in -optimize_init_evaluator()-. My question is this: Is there anyway to "clear" that function. After optimizing once, I wanted to change the function, but -mata- would not let me redefine the function because it was currently in use. So, I wanted to clear it out of the -optimize()- platform. Any ideas? -- P

    p.s. I ended up just defining a new function and declaring that in a new call to -optimize_init_evaluator()-, but seems rather inelegant.

  • #2
    Originally posted by Paul Rathouz View Post
    . . . Is there anyway to "clear" that function. After optimizing once, I wanted to change the function, but -mata- would not let me redefine the function because it was currently in use. So, I wanted to clear it out of the -optimize()- platform. Any ideas?
    optimize() allows you to pass arguments to your evaluator function, and these arguments can include pointers to other functions.

    So, one approach is to feed a façade function (wrapper) to in the guise of the evaluator function to optimize_init_evaluator() and then pass a pointer to the actual evaluator function to the wrapper evaluator function via optimize_init_argument(). This allows you to swap out the actual evaluator function at will.

    I illustrate the approach below using a couple of toy functions.
    Code:
    version 18.0
    
    clear *
    
    mata:
    
    mata set matastrict on
    
    real scalar function g1(real scalar x) return((x - 1)^2)
    
    real scalar function g2(real scalar x) return((x - 2)^2)
    
    void function façade(
        real scalar todo,
        real rowvector p,
        pointer(real scalar function) scalar g, // <= Here
        real scalar v,
        real rowvector G,
        real matrix H) {
            
            pragma unused todo
            pragma unused G
            pragma unused H
    
            v = (*g)(p) // <= and here
    
        }
    
    S = optimize_init()
    optimize_init_which(S, "min")
    optimize_init_evaluator(S, &façade())
    optimize_init_params(S, 0)
    
    // First (actual) evaluator function
    optimize_init_argument(S, 1, &g1())
    
    x = optimize(S)
    x
    
    // Second (actual) evaluator function
    optimize_init_argument(S, 1, &g2())
    
    x = optimize(S)
    x
    
    end
    
    exit
    I occasionally need to have state preserved between calls, and in those cases I use Mata's class programming features, passing an object to the façade (wrapper) function. If you need to swap actual evaluator function, then you can devise a class hierarchy where the actual evaluator functions are public methods on the child classes that are instantiated and then passed to the wrapper function as needed. Polymorphism allows the argument declaration in the façade function to be a little more facile.

    I wish that StataCorp would allow optimize_init_evaluator() to take objects as the second argument. It could impose a standardized interface (public evaluator method's name). It would allow more flexibility in setting up evaluator systems.

    Comment


    • #3
      Paul, I'm not sure if this works with -optimize- but a straightforward way to drop (or "undefine") a function in Mata can be seen here:
      Code:
      mata function fx(x) return(x)
      
      mata fx(1)
      
      mata mata drop fx()
      
      mata fx(1)
      Results:
      Code:
      . mata function fx(x) return(x)
      
      .
      . mata fx(1)
        1
      
      .
      . mata mata drop fx()
      
      .
      . mata fx(1)
                       <istmt>:  3499  fx() not found
      r(3499);
      
      end of do-file
      
      r(3499);
      
      .
      See
      Code:
      help mata drop

      Comment


      • #4
        Originally posted by John Mullahy View Post
        Paul, I'm not sure if this works with -optimize- but a straightforward way to drop (or "undefine") a function in Mata can be seen here:
        Yeah, it won't work with optimize(), because it appears to assign the pointer to a member variable of a persisting object, and you won't be able to drop the function while optimize() still has a pointer to it.
        Code:
        version 18.0
        
        clear *
        
        mata:
        mata set matastrict on
        
        void function f(real scalar todo, real rowvector P, real scalar v,
            real rowvector G, real matrix H) {}
        
        S = optimize_init()
        optimize_init_evaluator(S, &f())
        
        mata drop f()
        
        end
        
        exit
        The code above fails with a
        f() in use
        (nothing dropped)
        (1 line skipped)

        error message.

        The workaround that I suggested in #2 above doesn't really save Paul from much typing over what he ended up doing—just reassigning the pointer to a new function via another call to optimize_init_evaluator()—other than the laborious argument list required by optimize() of an evaluator function. (My original motivation was as I mentioned in order to use evaluator objects, which isn't allowed by optimize_init_evaluator().)

        Comment

        Working...
        X