Thread: problem with classes

  1. #16
    Registered User
    Join Date
    Nov 2008
    Posts
    9
    Actual code:
    Code:
    //Newton-Raphson Method
    //http://en.wikipedia.org/wiki/Newton's_method
    
    #include <cstdlib>
    #include <iostream>
    #include <math.h>
    
    using namespace std;
    
    //------------------------------------------------------------------------------
    
    class point
    {
       public:
          double x1, x2;
          double length()
          {
             return sqrt(pow(x1,2)+pow(x2,2)); //sqrt(x1^2+x2^2)
          }
          
          //I write that overloaded operator is a friend of this class.
          friend ostream & operator<<(ostream & theStream, point & thePoint);
    };
    
    //overloading operators point*double, double*point, point+point, point-point
    
    point operator*(point x, double a)
    {
       point result;
       result.x1 = x.x1 * a;
       result.x2 = x.x2 * a;
       return result;
    }
    
    point operator*(double a, point x)
    {
       point result;
       result.x1 = x.x1 * a;
       result.x2 = x.x2 * a;
       return result;
    }
    
    point operator+(point & thePoint1, point & thePoint2)
    {
       point sum;
       sum.x1 = thePoint1.x1 + thePoint2.x1;
       sum.x2 = thePoint1.x2 + thePoint2.x2;
       return sum;
    }
    
    point operator-(point & thePoint1, point & thePoint2)
    {
       point sum;
       sum.x1 = thePoint1.x1 - thePoint2.x1;
       sum.x2 = thePoint1.x2 - thePoint2.x2;
       return sum;
    }
    
    //overloaded operator <<
    ostream & operator<<(ostream & theStream, point & thePoint)
    {
       theStream<<"["<<thePoint.x1<<", "<<thePoint.x2<<"]";
       return theStream;
    }
    
    //------------------------------------------------------------------------------
    
    class hessian
    {
       public: //I've got a problem with determinant (in main function there is
               //a problem with compiling if I use 'private' here!!!!!!!!
          double x00, x01, x10, x11;
          //|x00 x01|
          //|x10 x11|
          double determinant;
       public:
          friend point operator*(hessian theHessian, point thePoint);
          friend hessian operator*(hessian theHes1, hessian theHes2);
          void det();
          void invertHessian();
          void hessianAtPoint(point thePoint);
          void hessianAtPoint();
          friend ostream&operator<<(ostream & theStream, hessian & theHessian);
    };
    
    //internal functions - determinant, invert hessian and hessian at point
    
    void hessian::det()
    { determinant = x00 * x11 - x10 * x01; }
    
    void hessian::invertHessian()
    {
       //inverted matrix: A^(-1) = A^D / det(A)
       //A = [(a, b), (c, d)], A^D = [(d, -b), (-c, a)]
       double _x00, _x01, _x10, _x11;
       _x00 =  x11/determinant;
       _x01 = -x01/determinant;
       _x10 =  x10/determinant;
       _x11 =  x00/determinant;
       x00 = _x00; x01 = _x01; x10 = _x10; x11 = _x11;
    }
    
    void hessian::hessianAtPoint()
    {
       x00 = x11 = 2;
       x01 = x10 = 0;
    }
    
    //overloading operators << and hessian*hessian
    
    ostream&operator<<(ostream & theStream, hessian & theHessian)
    {
       theStream<<"|"<<theHessian.x00<<" "<<theHessian.x01<<"|]n";
       theStream<<"|"<<theHessian.x10<<" "<<theHessian.x11<<"|]n";
       return theStream;
    }
    
    hessian operator*(hessian theHes1, hessian theHes2)
    {
       hessian result;
       //simple multiplication matrix by matrix
       //[a b][e f] = [ae+bg af+bh]
       //[c d][g h]   [ce+dg cf+dh]
       result.x00 = theHes1.x00 * theHes2.x00 + theHes1.x01 * theHes2.x10;
       result.x01 = theHes1.x00 * theHes2.x01 + theHes1.x01 * theHes2.x11;
       result.x10 = theHes1.x10 * theHes2.x00 + theHes1.x11 * theHes2.x10;
       result.x11 = theHes1.x10 * theHes2.x01 + theHes1.x11 * theHes2.x11;
       return result;
    }
    
    //------------------------------------------------------------------------------
    
    class gradient
    {
       public: //???????????????????
          point itsPoint;
       public:
          void gradientAtPoint(point thePoint);
          friend ostream&operator<<(ostream & theStream, gradient & theGradient);
    };
    
    void gradient::gradientAtPoint(point thePoint)
    {
       itsPoint.x1 = 2 * thePoint.x1 - 1;
       itsPoint.x2 = 2 * thePoint.x2 - 1;
    }
    
    ostream&operator<<(ostream & theStream, gradient & theGradient)
    {
       theStream<<theGradient.itsPoint;
       return theStream;
    }
    
    //------------------------------------------------------------------------------
    
    //overloading other operator: hessian*point
    
    point operator*(hessian theHessian, point thePoint)
    {
       point result;
       //[x00 x01] * [x1 x2] = [x00*x1 + x01*x2]
       //[x10 x11]             [x10*x1 + x11*x2]
       result.x1 = theHessian.x00 * thePoint.x1 + theHessian.x01 * thePoint.x2;
       result.x2 = theHessian.x10 * thePoint.x1 + theHessian.x11 * thePoint.x2;
       return result;
    }
    
    //main function
    
    double myFunction(point thePoint)
    { return (pow(thePoint.x1, 2)+pow(thePoint.x2, 2)); };
    
    //------------------------------------------------------------------------------
    
    int main()
    {
       //declaring variables
       gradient myGradient;
       hessian  myHessian;
       point    myPoint;
       point    tempPoint;
       double   accuracy;
       int      n = 0;
       
       //stating input variables
       cout<<"Write the input value x1 = ";
       cin>>myPoint.x1;
       cout<<"Write the input value x2 = ";
       cin>>myPoint.x2;
       cout<<"Write the accuracy = ";
       cin>>accuracy;
       
       //main algorithm
       myGradient.gradientAtPoint(myPoint);
       while (myGradient.itsPoint.length() > accuracy)
       {
          n++;
          myGradient.gradientAtPoint(myPoint);
          //myHessian.hessianAtPoint(myPoint);
          myHessian.hessianAtPoint();
          myHessian.det();
          myHessian.invertHessian();
          //myPoint = myPoint - (myHessian * (myGradient.itsPoint)); //[1]
          tempPoint = myHessian * myGradient.itsPoint;               //[2]
          myPoint = myPoint - tempPoint;                             //[3]
          //Here I changed line [1] into lines [2] and [3].
          //I think both [1] and [2][3] are the same but [1] doesn't compile.
       }
       
       //writing output
       cout<<"\n[x1, x2] = ["<<myPoint.x1<<", "<<myPoint.x2<<"]";
       cout<<"\nminimum value = "<<myFunction(myPoint);
       cout<<"\naccuracy = "<<accuracy;
       cout<<"\nnumber of iterations = "<<n<<"\n";
       system("PAUSE");
       return EXIT_SUCCESS;
    }
    
    //And by the way - I've got other question. If I'd like the user to be able to
    //change the function, is there any way to allow this application to read the
    //fuction (and gradient, hessian) from the file and put inside those lines which
    //are responsible for calculations?
    1. I changed
    Code:
    int main(int argc, char *argv[])
    into
    Code:
    int main()
    2. I decided to overload hessianAtPoint. I don't use hessianAtPoint(point thePoint) at all but I use hessianAtPoint.
    Code:
    void hessianAtPoint(point thePoint);
    void hessianAtPoint();
    Code:
    void hessian::hessianAtPoint()
    {
       x00 = x11 = 2;
       x01 = x10 = 0;
    }
    Code:
    //myHessian.hessianAtPoint(myPoint);
    myHessian.hessianAtPoint();
    You asked why I take myPoint into that function if I don't use it at all. It is because this program should calculate something. As "input" you've got function - here it is
    Code:
    //main function
    
    double myFunction(point thePoint)
    { return (pow(thePoint.x1, 2)+pow(thePoint.x2, 2)); };
    Then, with using calculations on the sheet of paper, I found hessian at point (matrix of partial derivatives) and gradient at point (some other partial derivatives). If the function is easy, then hessian and gradient may contain only numbers, like here:
    Code:
    x00 = x11 = 2;
    x01 = x10 = 0;
    But if function is more complicated, there may be other function dependent on thePoint, for example:
    Code:
    void HessianAtPoint(point c)
    {
    //x00=x11=2;
    //x01=x10=0;
    			x00=(((-2*((-7.9)*exp(-7.9*c.x1)+0.1*exp(0.1*c.x1))*pow(c.x2,2))/pow((exp(-7.9*c.x1)+exp(0.1*c.x1)),2))+((-2*((-7.9)*exp(-7.9*c.x1)+0.1*exp(0.1*c.x1))*(-1+c.x1*pow(c.x2,2)))/pow((exp(-7.9*c.x1)+exp(0.1*c.x1)),3))-((((62.41)*exp(-7.9*c.x1)+0.01*exp(0.1*c.x1))*(-1+c.x1*pow(c.x2,2)))/pow((exp(-7.9*c.x1)+exp(0.1*c.x1)),2)));
    
    x01=x10=((2*c.x2*(exp((-7.9)*c.x1)+exp(0.1*c.x1))-2*c.x1*c.x2*((-7.9)*exp((-7.9)*c.x1)+0.1*exp(0.1*c.x1)))/(pow((exp(-7.9*c.x1)+exp(0.1*c.x1)),2)));
    
    x11=((2*c.x1)/(exp(-7.9*c.x1)+exp(0.1*c.x1)));
    }
    I don't know how to create "dynamic" which take formula of function, formulas of hessian at point and formulas of gradient at point. This is why I decided to write it inside the code and not to take it as a parameter from the user. So if I want to use this program for other function, I need to change some lines inside the code and recompile it.

    3. I added return:
    Code:
    ostream&operator<<(ostream & theStream, hessian & theHessian)
    {
       theStream<<"|"<<theHessian.x00<<" "<<theHessian.x01<<"|]n";
       theStream<<"|"<<theHessian.x10<<" "<<theHessian.x11<<"|]n";
       return theStream;
    }
    4. I don't understand this error
    Error 5 error C4716: 'operator*' : must return a value g:\w00t\visual studio 2008\projects\temp\temp2.cpp 126
    I have got:
    Code:
    hessian operator*(hessian theHes1, hessian theHes2)
    {
       hessian result;
       //simple multiplication matrix by matrix
       //[a b][e f] = [ae+bg af+bh]
       //[c d][g h]   [ce+dg cf+dh]
       result.x00 = theHes1.x00 * theHes2.x00 + theHes1.x01 * theHes2.x10;
       result.x01 = theHes1.x00 * theHes2.x01 + theHes1.x01 * theHes2.x11;
       result.x10 = theHes1.x10 * theHes2.x00 + theHes1.x11 * theHes2.x10;
       result.x11 = theHes1.x10 * theHes2.x01 + theHes1.x11 * theHes2.x11;
       return result;
    }
    Result is hessian, hessian has got four internal variables:
    Code:
    class hessian
    {
       public: //I've got a problem with determinant (in main function there is
               //a problem with compiling if I use 'private' here!!!!!!!!
          double x00, x01, x10, x11;
    So I'm just writing resulting x00, x01, x10 and x11 into object which is hessian. To tell the truth I don't remember where I used (or whether I used) this overloaded operator to multiply hessian by hessian so probably I don't need to overload this operator hessian*hessian and I can simply remove this part of code.

    5. I added
    return result;
    into
    Code:
    //overloading other operator: hessian*point
    
    point operator*(hessian theHessian, point thePoint)
    {
       point result;
       //[x00 x01] * [x1 x2] = [x00*x1 + x01*x2]
       //[x10 x11]             [x10*x1 + x11*x2]
       result.x1 = theHessian.x00 * thePoint.x1 + theHessian.x01 * thePoint.x2;
       result.x2 = theHessian.x10 * thePoint.x1 + theHessian.x11 * thePoint.x2;
       return result;
    }
    Regards

  2. #17
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by zdzislavv View Post
    Code:
    void HessianAtPoint(point c)
    You couldn't wrap that in several lines or simplify that formula? It's completely unreadable, pretty much, and way too long.
    Perhaps loop will help.
    4. I don't understand this error
    It means that the function returns something, but you don't have a "return" line anywhere.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #18
    Registered User
    Join Date
    Nov 2008
    Posts
    9
    I thought I've got return here:

    Code:
    hessian operator*(hessian theHes1, hessian theHes2)
    {
       hessian result;
       //simple multiplication matrix by matrix
       //[a b][e f] = [ae+bg af+bh]
       //[c d][g h]   [ce+dg cf+dh]
       result.x00 = theHes1.x00 * theHes2.x00 + theHes1.x01 * theHes2.x10;
       result.x01 = theHes1.x00 * theHes2.x01 + theHes1.x01 * theHes2.x11;
       result.x10 = theHes1.x10 * theHes2.x00 + theHes1.x11 * theHes2.x10;
       result.x11 = theHes1.x10 * theHes2.x01 + theHes1.x11 * theHes2.x11;
       return result;
    }
    In first line I see that this operator should return hessian. Inside the function I create hessian result and at the end I return result which is hessian.

  4. #19
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yeah, you added that one later, so that should take care of the error.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #20
    Registered User
    Join Date
    Nov 2008
    Posts
    9
    So I guess now I've got working code with no warnings and no errors (in Dev-C++'s compiler there are no errors and I hope there shouldn't be any in the other compiler). Thanks a lot for your help . I guess there are some other things which may be improved in this code (for example proper way of choosing which variables are private and which are public in classes). Are these classes constructed properly or should I change something?

  6. #21
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, member variables should be private or protected.
    You should expose getters / setters instead.
    This makes your code more robust if those internal variables should be changed, its meaning changed or disappear.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. problem with classes and pointers
    By Akkernight in forum C++ Programming
    Replies: 18
    Last Post: 02-21-2009, 06:21 AM
  2. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  3. Having a problem with Classes
    By FoxTrot in forum C++ Programming
    Replies: 10
    Last Post: 09-06-2007, 07:40 PM
  4. Problem with destructors.
    By Hulag in forum C++ Programming
    Replies: 7
    Last Post: 06-11-2004, 12:30 PM
  5. problem w/ nested templatized classes
    By *ClownPimp* in forum C++ Programming
    Replies: 8
    Last Post: 10-19-2002, 07:58 AM