Funktionsuntersuchung
Dieses Programm dient dazu, Funktionsuntersuchungen von Funktionen zu machen.
function.cpp
/* * Function - a program to calculate with polynomial functions * Copyright (C) 2005 Nicolas Bellm * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * g++ function.cpp * */ #include <iostream> #include <sstream> #include <math.h> #include "function.h" double Function::f(double x) { double ret = k[0]; for (int i = 1; i < k.size(); i++) ret = ret * x + k[i]; return ret; } Function* Function::derive() { vector<double> ret( degree() ); for (int i = 0; i < ret.size(); i++) ret[i] = k[i] * ( degree() - i ); string name = m_name + "'"; return new Function( name, ret ); } Function* Function::derive(int i) { Function *f = this; for (int j=0; j<i; j++) f = f->derive(); return f; } list<double> Function::roots() { list<double> ret; double d, p, q; switch ( degree() ) { case 0: if ( k[0] == 0 ) ret.push_back( 0 ); break; case 1: ret.push_back( -k[1] / k[0] ); break; case 2: d = k[1] * k[1] - 4 * k[0] * k[2]; if ( d > 0 ) { ret.push_back( ( -k[1] + sqrt( d ) ) / ( 2 * k[0] ) ); ret.push_back( ( -k[1] - sqrt( d ) ) / ( 2 * k[0] ) ); } else if ( d == 0 ) { ret.push_back( -k[1] / ( 2 * k[0] ) ); } break; case 3: p = k[2]/k[0]-(k[1]*k[1])/(3*k[0]*k[0]); q = k[3]/k[0]+(2*k[1]*k[1]*k[1])/(27*k[0]*k[0]*k[0])-(k[1]*k[2])/(3*k[0]*k[0]); d = (q*q)/4+(p*p*p)/27; if ( d > 0 ) ret.push_back( cbrt(-q/2+sqrt(q*q/4+p*p*p/27))+ cbrt(-q/2-sqrt(q*q/4+p*p*p/27))-k[1]/3*k[0] ); else if ( d == 0 ) // Rundungsfehler ? { ret.push_back( cbrt(q/2)-k[1]/(3*k[0]) ); ret.push_back( -cbrt(4*q)-k[1]/(3*k[0]) ); } else { ret.push_back( 2*sqrt(-p/3)*cos(1/3.*acos(-q/2*sqrt(-27/(p*p*p))))-k[1]/(3*k[0]) ); ret.push_back( -2*sqrt(-p/3)*cos(1/3.*acos(-q/2*sqrt(-27/(p*p*p)))+M_PIl/3)-k[1]/(3*k[0]) ); ret.push_back( -2*sqrt(-p/3)*cos(1/3.*acos(-q/2*sqrt(-27/(p*p*p)))-M_PIl/3)-k[1]/(3*k[0]) ); } break; } return ret; } list<Point> Function::extrema() { list<double> roots = derive()->roots(); list<Point> ret; for (list<double>::iterator it = roots.begin(); it != roots.end(); it++) { Point p(*it,f(*it)); ret.push_back(p); } return ret; } string Function::toString() { ostringstream ret; ret << m_name << "(x) = "; int i; for (i = 0; i < k.size(); i++) { if ( k[i] != 0 ) { if ( k[i] > 0 ) { if ( i != 0 ) ret << "+ "; } else ret << "- "; if ( fabs( k[i] ) != 1 || degree() - i == 0 ) ret << fabs( k[i] ); if ( degree() - i >= 2 ) ret << "x^" << degree() - i; else if ( degree() - i == 1 ) ret << "x"; ret << " "; } } return ret.str(); } int main() { int grad, auswahl; vector<double> p; cout << "Grad der Funktion: "; cin >> grad; p.resize( grad + 1 ); for (int i = 0; i <= grad; i++) { cout << "Koeffizient von x^" << grad-i << ": "; cin >> p[i]; } Function f( "f", p ); while(true) { cout << "Was wollen Sie tun?" << endl << "[1] Funktion anzeigen" << endl << "[2] Funktionswert berechnen" << endl << "[3] Funktion ableiten" << endl << "[4] Nullstellen berechnen" << endl << "[5] Extrempunkte berechnen" << endl << "[6] Wendepunkte berechnen" << endl << "[7] Beenden" << endl << "Auswahl: "; cin >> auswahl; switch( auswahl ) { case 1: cout << f.toString() << endl; break; case 2: { int i; cout << "Funktionswert: "; cin >> i; cout << "f(" << i << ") = " << f.f(i) << endl; break; } case 3: { int i; cout << "n-te Ableitung: "; cin >> i; cout << f.derive(i)->toString() << endl; break; } case 4: { list<double> v = f.roots(); for(list<double>::iterator it = v.begin(); it != v.end(); it++) cout << "N(" << *it << "|0)" << endl; break; } case 5: { list<Point> w = f.extrema(); for(list<Point>::iterator it = w.begin(); it != w.end(); it++) cout << "E(" << (*it).x() << "|" << (*it).y() << ")" << endl; break; } case 6: { list<Point> w = f.derive()->extrema(); for(list<Point>::iterator it = w.begin(); it != w.end(); it++) cout << "W(" << (*it).x() << "|" << (*it).y() << ")" << endl; break; } case 7: return 0; default: cerr << "Fehlerhafte Eingabe! Bitte geben sie eine Zahl zwischen 1 und 7 ein." << endl; } } }
function.h
/* * Function - a program to calculate with polynomial functions * Copyright (C) 2005 Nicolas Bellm * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * */ #include <vector> #include <list> #include <string> using namespace std; class Point { public: Point() { m_x = 0; m_y = 0; } Point(double x, double y) { m_x = x; m_y = y; } void setX(double x) { m_x = x; } void setY(double y) { m_y = y; } double x() { return m_x; } double y() { return m_y; } private: double m_x, m_y; }; class Function { public: Function(string name, vector<double> &_k) { m_name = name; k = _k; }; ~Function() {} double f(double x); list<double> roots(); Function* derive(); Function* derive(int i); int degree() { return k.size() - 1; }; list<Point> extrema(); string toString(); private: string m_name; vector<double> k; // Koeffizienten };