stimmt das so?



  • Hallo!

    ich soll ein übungsbeispiel programmieren, welches eine abstrakte klasse Function, eine abgeleitete klasse Polynomial und eine funktion simpson, die das bestimmte integral einer beliebigen funktion mit der simpson methode berechnet, enthält.

    ich hab mal so drauf los geschrieben und wollte euch fragen, was ihr davon hält.

    //  Function.hpp
    
    #pragma once
    #include <cstdlib>
    
    class Function {
    public:
    
        virtual double operator() (double x) const = 0;
        virtual ~Function() {};
    };
    
    //  Gauss.hpp
    
    #pragma once
    
    #include "Function.hpp"
    #include <cmath>
    
    //====================================================================
    //! Example function object - Gauss' bell curve
    class Gauss : public Function {
    public:
        //! The bell curve ...
        virtual double operator() (double x) const {
            return m_a*std::exp(-std::pow(x-m_x0,2.)/std::pow(m_w,2.0));
        }
        //! Set the parameters for the bell curve
        //! \param a Amplitude
        //! \param x0 center
        //! \param w width
        void setParameters(double a, double x0, double w);
    private:
        double m_a;
        double m_w;
        double m_x0;
    };
    
    //  Polynomial.hpp
    
    #pragma once
    #include <cstdlib>
    #include "Function.hpp"
    
    ///@@ NOTE: Polynomial must be derived from Function!
    class Polynomial : public Function {
    public:
        //! Default constructor
        //! Creates 0th-order polynomial p(x) = 0
        Polynomial();
        //
        //! Constructor: Construct polynomial with given coefficients
        //! The coefficients are copied and stored by the class, the
        //! pointer pc to the original array is *not* used again.
        //! \param pc pointer to coefficient array
        //! \param number of coefficients (=order of polynomial)
        Polynomial(const double* const pc, size_t n);
    
    	~Polynomial();
    
        //
        //! Set polynomial coefficients. Coefficients are copied, the
        //! pointer pc is never used again.
        //! \param pc pointer to coefficient array
        //! \param number of coefficients (=order of polynomial)
        void setCoefficients(const double* const pc, size_t n);
    
    	virtual double operator() (double x) const;
    
    private:
        ///@@ you *must* use a plain-C double array to store
        ///@@ the coefficients of the polynomial, std::vector is NOT allowed
        double * pc_;
        size_t n_;
    };
    
    //  simpson.hpp
    
    #pragma once
    
    #include "Function.hpp"
    
    double simpson(const Function& func, double a, double b, int n);
    
    //  Gauss.cpp
    
    #include "Gauss.hpp"
    
    #include <iostream>
    
    void Gauss::setParameters(double a, double x0, double w) {
        m_a = a;
        m_w = w;
        m_x0 = x0;
    }
    
    //  Polynomial.cpp
    
    #include "Polynomial.hpp"
    #include <iostream>
    #include <math.h>
    
    using namespace std;
    
    Polynomial::Polynomial(const double* const pc, size_t n) : n_(n) {
    	pc_ = new double[n];
    	for (size_t i = 0; i < n; ++i) {
    		pc_[i] = pc[n-i-1];
    		cout << pc_[i] << endl;
    	}
    	setCoefficients(pc_, n_);
    }
    
    Polynomial::~Polynomial() {
    	delete[] pc_;
    }
    void Polynomial::setCoefficients(const double* const pc, size_t n) {
    	cout << "p(x) = ";
    		for (size_t i = 0; i < n; ++i) {
    			cout << pc[i] << " * x^" << i << " + ";
    		}
    		cout << endl;
    }
    
    double Polynomial::operator() (double x) const {
    	double y = 0;
    	for (size_t i = 0; i < n_; ++i) {
    		y += pc_[i] * std::pow(x,i);
    	}
    	return y;
    }
    
    //  simpson.cpp
    
    #include "simpson.hpp"
    #include <math.h>
    #include <iostream>
    
    using namespace std;
    
    double simpson(const Function& func, double a, double b, int n) {
    	double h = (b - a) / n;
    	double sum = func(a) + func(b);
    	for (int i = 1; i <= (n / 2 - 1); i++)
    		sum += 2.0*func(a + (2 * i)*h);
    	for (int i = 1; i <= (n / 2); i++)
    		sum += 4.0*func(a + (2 * i - 1)*h);
    	return (h / 3 * sum);
    }
    
    //  main.cpp
    
    #include <iostream>
    #include <cmath>
    
    #include "Gauss.hpp"
    #include "Polynomial.hpp"
    
    #include "simpson.hpp"
    
    using namespace std;
    
    const double pi = acos(-1);
    
    int main(int argc, const char * argv[])
    {
    
        Gauss myGauss;
        myGauss.setParameters(1./sqrt(pi),0.,1.);
    
        double integral = simpson(myGauss, -20.0, 20.0, 100);
        cout << integral << endl;
    
        double c[3] = {-2,-1,1};
        Polynomial p(c,3);
        integral = simpson(p, -2, 1, 10000);
        cout << integral << endl;
    	system("pause");
        return 0;
    }
    

    Vielen Dank!! 🙂



  • ob die implementierung der simpson-integrierung stimmt kann ich dir nicht sagen, das weiss ich nicht.

    ich sehe die implementierung des standardkonstruktors der polynom-klasse nicht. ausserdem stimmt dein code so nicht, überleg dir was die compilergenerierten kopierkonstruktoren und zuweisungsoperatoren der polynomklasse machen. das kommt davon wenn man std::vector aus willkür verbietet.
    und müsste Polynomial::setCoefficients nicht das selbe machen wie der eine konstruktor?

    -snip-

    edit: hab nicht nachgedacht. am besten noch eine swap-methoden implementieren. dann wird das ganze mit der manuellen speicherverwaltung einfacher.

    edit: am besten einfach einen std::vector in ganz groben zügen nachimplementieren und dann in der polynom-klasse nutzen. dann sind die aufgaben logisch getrennt.


Log in to reply