W
Balkohol schrieb:
Da ich wie gesagt erst seit kurzem c++ programmiere und ich fast direkt in c++ vom hallo welt zu diesem programm übergegangen bin ...
Mutig, mutig!
Balkohol schrieb:
Also er meckert halt rum das ich in der Funktion Termableitung die Array nicht so definieren kann - das soll er ja aber auch erst amchen wenn ich die Funktion aufrufe(!!).
Ja, das ist richtig. In C++ kannst Du keine dynamischen Arrays auf den Stack legen. In diesem Fall kannst Du statt dessen std::vector<> benutzen. Also etwa so:
void Termableitung()
{
using namespace std;
// Arraydefinition
vector< int > spalte1(n);
vector< double > spalte11(n);
vector< double > spalte12(n);
// Es Folgen Die Ableitungen der Einzelnen Terme
// ...
Dazu braucht man dann noch ein #include <vector> damit's funkt.
Im Übrigen würde ich Dir aber stark empfehlen einen anderen Ansatz zu benutzen. Die globale Variablen-Deklaration ist .. sagen wir leicht daneben.
Da ist doch das Produkt aus zwei Funktionen
sin(x)x47sin(x) x^{\frac{4}{7}}sin(x)x74
deren Natur sich durch Ableiten nicht wesentlich verändert. Da ist es angebracht dafür eine Klasse zu schreiben.
class Trigo // Funktion +/-sin(x) bzw. +/-cos(x)
{
public:
enum { sin_x = 1, cox_x = 2 };
explicit Trigo( int typ = sin_x ) : m_typ( typ ) {}
Trigo derivation() const { // Ableitung bestimmen
int typ = 0;
switch( m_typ ) {
case sin_x: typ = cox_x; break;
case cox_x: typ = -sin_x; break;
case -sin_x: typ = -cox_x; break;
case -cox_x: typ = sin_x; break;
}
return Trigo( typ );
}
friend std::ostream& operator<<( std::ostream& out, const Trigo& trigo )
{
using namespace std;
if( trigo.m_typ < 0 ) out << "-";
if( abs( trigo.m_typ ) == Trigo::sin_x )
return out << "sin(x)";
return out << "cos(x)";
}
private:
int m_typ;
};
Ich weiß, Du bist Anfänger .. aber ich gehe gleich in die Vollen. Schau Dir erstmal die Anwendung an:
#include <iostream>
// #include Trigo.h (s.o.)
int main()
{
using namespace std;
Trigo f( Trigo::sin_x );
cout << "Funktion " << f << endl;
for( int n=1; n<=4; ++n )
cout << n << ".Ableitung: " << (f = f.derivation()) << endl;
return 0;
}
Im Grunde besteht die Klasse Trigo nur aus einem int, was die Werte 1,2,-1 und -2 annehmen kann, genau wie Du das vorher mit den Werten 1 bis 4 gemacht hast. Nur das alles inklusive der Ableitung (Methode derivation()) und der Ausgabe (operator<<) in einer Klasse untergebracht wird.
Das gleiche für die andere Funktion
template< typename T >
class X_hoch // Funktion fac*x^(exp)
{
public:
typedef T value_type;
X_hoch() : m_fac(0), m_exp(1) {}
X_hoch( value_type fac, value_type exp ) : m_fac( fac ), m_exp( exp ) {}
X_hoch derivation() const { // Ableitung bestimmen
if( m_exp == value_type(0) ) // Sonderbehandlung für Konstante
return X_hoch();
return X_hoch( m_exp * m_fac, m_exp - value_type(1) );
}
friend std::ostream& operator<<( std::ostream& out, const X_hoch& xh )
{
if( xh.m_fac == value_type(0) || xh.m_exp == value_type(0) )
return out << xh.m_fac;
if( xh.m_fac == value_type(-1) )
out << "-";
else if( xh.m_fac != value_type(1) )
out << xh.m_fac;
if( xh.m_exp == value_type(1) )
out << "x";
else
out << "x^(" << xh.m_exp << ")";
return out;
}
private:
value_type m_fac, m_exp;
};
Diesmal aber als Template. So kann man den Typ für den Exponenten frei wählen. Falls Du die boost-Library hast oder installierst, so kannst Du hier boost::rational verwenden. Ansonsten einfach double benutzen.
Wieder ein kleines Testprogramm
#include <iostream>
#include <boost/rational.hpp>
// #include "X_hoch.h" (s.o.)
int main()
{
using namespace std;
X_hoch< boost::rational< int > > f( 1, boost::rational< int >( 4, 7 ) );
// oder: X_hoch< double > f( 1, 4.0/7.0 );
cout << "Funktion " << f << endl;
for( int n=1; n<=4; ++n )
cout << n << ".Ableitung: " << (f = f.derivation()) << endl;
return 0;
}
Hier erhält man als Ausgabe:
Funktion x^(4/7)
1.Ableitung: 4/7x^(-3/7)
2.Ableitung: -12/49x^(-10/7)
3.Ableitung: 120/343x^(-17/7)
4.Ableitung: -2040/2401x^(-24/7)
So jetzt noch eine kleine Funktion, die alle Ableitungen von 1 bis n erzeugt. Da die für beide Typen benötgt wird, das ganze wieder als Template:
template< typename F, typename SZ >
std::vector< F > make_derivations( F funk, SZ n )
{
std::vector< F > erg( 1, funk ); // Funktion selbst ist 0'te Ableitung
for( ; n > 0; --n ) {
funk = funk.derivation();
erg.push_back( funk );
}
return erg;
}
Und dann das Ganze zusammenstecken und ausgeben
int main()
{
using namespace std;
Trigo trigo( Trigo::sin_x );
X_hoch< boost::rational< int > > x_hoch( 1, boost::rational< int >( 4, 7 ) );
cout << "Gegeben ist die Funktion " << trigo << "*" << x_hoch << endl;
cout << "Geben Sie den Grad der gewuenschten Abeitung ein. " << endl;
for( int n; cout << "n=", cin >> n; )
{
vector< Trigo > trigos = make_derivations( trigo, n );
vector< X_hoch< boost::rational< int > > > x_hochs = make_derivations( x_hoch, n );
vector< Trigo >::iterator i_trigo = trigos.begin();
vector< X_hoch< boost::rational< int > > >::reverse_iterator i_x_hoch = x_hochs.rbegin();
bool plus_sign = false;
for( BinomKoeff bk(n); *bk; ++bk, ++i_trigo, ++i_x_hoch )
{
if( plus_sign ) cout << " + "; else plus_sign = true;
if( *bk != 1 ) cout << *bk << "*";
cout << *i_trigo << "*" << *i_x_hoch;
}
cout << endl;
}
return 0;
}
Und so sollte der Output aussehen:
Gegeben ist die Funktion sin(x)*x^(4/7)
Geben Sie den Grad der gewuenschten Abeitung ein.
n=2
sin(x)*-12/49x^(-10/7) + 2*cos(x)*4/7x^(-3/7) + -sin(x)*x^(4/7)
n=0
sin(x)*x^(4/7)
n=
.. starker Tobak für einen Anfänger - klar, aber versuch' mal Dich durchzukämpfen. Viel Spaß!
Gruß
Werner