Announcement

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

  • How to call an objective function in a class

    Hi, I am writing a mata source code.
    In my code, the structure is as follows:
    Code:
    mata:
    class my_class {
        public:
        void my_obj(), my_deriv()
    }
    
    void my_class::new() {
        some objects
    }
    
    void my_class::my_obj() {
        function's body
    }
    
    void my_class::my_deriv() {
        transmorphic D
        real matrix scores, Hessian
    
        D = deriv_init()
        deriv_init_evaluator(D, &my_obj())                                                             // Note here
        
         continue ...
    }
    end
    I expected that the function my_deriv() works because both my_deriv() and my_obj() are declared and defined in the same class.
    But, when I implemented this code like below
    Code:
    mata: m = my_class()
    mata: m.my_deriv()
    The following error is returned:

    my_class::my_deriv(): 3499 my_obj() not found
    <istmt>: - function returned error

    What is the problem here?

  • #2
    Try begin explicitly
    Code:
    ...
    deriv_init_evaluator(D, &this.my_obj())
    ...

    Comment


    • #3
      daniel klein Thank you so much. Your suggestion works perfectly! I have forgotten that we can explicitly say that the function is in the same class. Thank you.

      Comment


      • #4
        Originally posted by Minch Park View Post
        Your suggestion works perfectly!
        It does?

        I've never been able to get Mata's optimize() to accept a pointer to an object's public method as an evaluator.

        And it seems that deriv() exhibits the same behavior—see below.

        I use your code verbatim, adding arguments and an actual function to evaluate within my_obj()
        Code:
        version 18.0
        
        clear *
        
        mata:
        
        class my_class {
            public:
                void my_obj(), my_deriv()
        }
        
        /* void my_class::new() {
            some objects
        } */
        
        void my_class::my_obj(x, y) {
            y = x^2 + x - 3
        }
        
        void my_class::my_deriv() {
            transmorphic D
            real matrix scores, Hessian
        
            D = deriv_init()
            deriv_init_evaluator(D, &this.my_obj())
        
        }
        
        end
        
        mata: m = my_class()
        mata: m.my_deriv()
        
        exit
        It gives the same type of error message that I get with optimize() under analogous usage, namely:

        .ÿ
        .ÿmata:ÿmÿ=ÿmy_class()

        .ÿmata:ÿm.my_deriv()
        ÿÿÿÿÿÿmy_class::my_obj():ÿÿ3001ÿÿexpectedÿ3ÿargumentsÿbutÿreceivedÿ1
        ÿÿÿÿmy_class::my_deriv():ÿÿÿÿÿ-ÿÿfunctionÿreturnedÿerror
        ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ<istmt>:ÿÿÿÿÿ-ÿÿfunctionÿreturnedÿerror
        r(3001);

        endÿofÿdo-file

        r(3001);


        What am I doing wrong?

        Comment


        • #5
          Joseph Coveney You are right, the code results in "another problem" as you mentioned. I think, my reply caused some confusion.
          My gist was "Why does Mata fail to find the function", and the prefix this. answers to the specific question.
          On top of that, based on the answer from Klein, I found the reason for the subsequent error you mentioned as well (https://www.stata.com/statalist/arch.../msg00159.html)
          So, I decided to let the functions outside the class, and the problem was entirely solved.

          Comment


          • #6
            Originally posted by Minch Park View Post
            . . .the code results in "another problem" as you mentioned. . . . So, I decided to let the functions outside the class, and the problem was entirely solved.
            I typically use an external standalone function as a front, similar to what's shown here except that rather than passing a pointer to another function through optimize_init_argument() as shown in that example, I pass the object, kind of a callback. Unlike with functions there's no need to go through the extra effort to create pointers to objects in order to pass them through.

            Comment


            • #7
              Joseph Coveney Thank you for the details. Now my code has exactly same structure to your recommendation. I really appreciate that I can understand more advanced Mata programming. Thank you again.

              Comment

              Working...
              X