<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Operator überladen für Zahlen und nicht speziell für double]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe mir eine Klasse für Polynome geschrieben und dabei die Operatoren +=, *=, etc.. in der Klasse und *, +, - global überladen.</p>
<p>Jetzt soll man das Polynom auch mit einer &quot;normalen Zahl&quot; multiplizieren können (short, int, Long, double, float) - hab die Methoden aber bisher nur für double implementiert und gemerkt, dass mein Compiler die Zahlen nicht einfach entsprechend castet -<br />
Muss ich jetzt den Quellcode komplett kopieren und auf die anderen Datentypen umschreiben oder kann man da was mit Templates machen?</p>
<p>Wie würde das dann funktionieren - ich meine da sollen ja nur ein paar Membermethoden (die überladenen Operatoren) allgemein gültiger werden und nicht die ganze Klasse.</p>
<p>Vielen Dank für eine Antwort,</p>
<p>viele Grüße</p>
<p>Andreas</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/260919/operator-überladen-für-zahlen-und-nicht-speziell-für-double</link><generator>RSS for Node</generator><lastBuildDate>Mon, 07 Sep 2026 21:30:47 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/260919.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 10 Feb 2010 19:17:27 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Wed, 10 Feb 2010 19:17:27 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe mir eine Klasse für Polynome geschrieben und dabei die Operatoren +=, *=, etc.. in der Klasse und *, +, - global überladen.</p>
<p>Jetzt soll man das Polynom auch mit einer &quot;normalen Zahl&quot; multiplizieren können (short, int, Long, double, float) - hab die Methoden aber bisher nur für double implementiert und gemerkt, dass mein Compiler die Zahlen nicht einfach entsprechend castet -<br />
Muss ich jetzt den Quellcode komplett kopieren und auf die anderen Datentypen umschreiben oder kann man da was mit Templates machen?</p>
<p>Wie würde das dann funktionieren - ich meine da sollen ja nur ein paar Membermethoden (die überladenen Operatoren) allgemein gültiger werden und nicht die ganze Klasse.</p>
<p>Vielen Dank für eine Antwort,</p>
<p>viele Grüße</p>
<p>Andreas</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1853834</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1853834</guid><dc:creator><![CDATA[Andreas_L]]></dc:creator><pubDate>Wed, 10 Feb 2010 19:17:27 GMT</pubDate></item><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Wed, 10 Feb 2010 19:39:57 GMT]]></title><description><![CDATA[<p>so in etwa?</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
struct polynom
{
  typedef T value_type;

  template&lt;typename U&gt;
  explicit polynom(const polynom&lt;U&gt;&amp; other)
  : coeff(other.coeff.size())
  {
    coeff_container::const_iterator j(other.coeff.begin());
    for(coeff_container::const i(coeff.begin()), e(coeff.end()); i != e; ++i, ++j)
      *i = static_cast&lt;value_type&gt;(*j);
  }

  template&lt;typename U&gt;
  polynom&amp; operator*= (const polynom&lt;U&gt;&amp; other)
  {
    /*..rechnen..*/

    return *this;
  }

  template&lt;typename U&gt;
  polynom&amp; operator*= (U skalar)
  {
    /*..rechnen..*/;

    return *this;
  }
private:
  typedef std::vector&lt;value_type&gt; coeff_container; //oder wie auch immer koeffizienten auf englisch heißt ;D
  coeff_container coeff;
};

template&lt;typename T, typename U&gt;
polynom&lt;T&gt; operator* (const polynom&lt;T&gt;&amp; lhs, const U&amp; rhs)
{
  polynom&lt;T&gt; ret_val(lhs);
  lhs *= rhs;
  return lhs;
}

int main()
{
  polynom&lt;float&gt; b(/*...*/);
  polynom&lt;double&gt; c(/*...*/);

  polynom&lt;int&gt; a = polynom&lt;int&gt;(c) * polynom&lt;int&gt;(b);
  a = a * 5;
  b *= 3;
}
</code></pre>
<p>sollte so laufen, wenn mich nicht alles täuscht - und auch genau das machen, was du möchtest, oder?</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1853844</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1853844</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Wed, 10 Feb 2010 19:39:57 GMT</pubDate></item><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Wed, 10 Feb 2010 20:04:35 GMT]]></title><description><![CDATA[<p>Hi,<br />
sieht im Moment so aus als würde es funktionieren <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":-)"
      alt="🙂"
    /><br />
Also schonmal vielen Dank!!</p>
<p>Mal ne Frage zu einem Code:</p>
<pre><code class="language-cpp">template&lt;typename T, typename U&gt;
polynom&lt;T&gt; operator* (const polynom&lt;T&gt;&amp; lhs, const U&amp; rhs)
{
  polynom&lt;T&gt; ret_val(lhs);
  lhs *= rhs;
  return lhs;
}
</code></pre>
<p>Musst du nicht ret_val *= rhs nehmen, sonst überschreibst du doch einen Faktor oder nicht?</p>
<p>Kann man das folgende wirklich so kompilieren - greifst du nicht auf private Variablen zu?</p>
<pre><code class="language-cpp">template&lt;typename U&gt;
  explicit polynom(const polynom&lt;U&gt;&amp; other)
  : coeff(other.coeff.size())
  {
    coeff_container::const_iterator j(other.coeff.begin());
    for(coeff_container::const i(coeff.begin()), e(coeff.end()); i != e; ++i, ++j)
      *i = static_cast&lt;value_type&gt;(*j);
  }
</code></pre>
<p>Viele Grüße</p>
<p>Andreas</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1853852</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1853852</guid><dc:creator><![CDATA[Andreas_L]]></dc:creator><pubDate>Wed, 10 Feb 2010 20:04:35 GMT</pubDate></item><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Wed, 10 Feb 2010 21:35:36 GMT]]></title><description><![CDATA[<p>Bei mir ist leider noch ein kleines Problem aufgetaucht.</p>
<p>In der Polynomklasse sind u.a. folgende Methoden deklariert:</p>
<pre><code class="language-cpp">CPolynom(unsigned short Grad);
CPolynom(void);
CPolynom&amp; operator=(CPolynom&amp; AnderesPolynom); 
template&lt;typename U&gt; 
CPolynom&amp; operator=(const U&amp; Zahl);
</code></pre>
<p>Jetzt habe ich eine Matrix als Template aufgebaut, deren Einträge nun also die Polynome enthalten soll. In einer Zeile steht dabei:</p>
<pre><code class="language-cpp">template &lt;class Datentyp&gt;
Datentyp CMatrix&lt;Datentyp&gt;::Determinante_Rekursiv()
{
/*....*/
Datentyp Unterdeterminante = 0;
/*...*/
}
</code></pre>
<p>Wobei für Datentyp ja das Polynom verwendet wird.<br />
Jetzt hätte ich gedacht, dass von den oberen Operatoren der Zuweisungsoperator CPolynom&amp; operator=(const U&amp; Zahl); verwendet wird. Stattdessen wird aber der Konstruktor aufgerufen, wobei die 0 im als Grad des Polynoms übergeben wird.<br />
Warum macht er das und was kann man dagegen machen - schließlich wird so die Unterdeterminante nicht ordnungsgemäß eingerichtet.</p>
<p>Vielen Dank und viele Grüße</p>
<p>Andreas</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1853897</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1853897</guid><dc:creator><![CDATA[Andreas_L]]></dc:creator><pubDate>Wed, 10 Feb 2010 21:35:36 GMT</pubDate></item><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Wed, 10 Feb 2010 21:50:04 GMT]]></title><description><![CDATA[<p>Andreas_L schrieb:</p>
<blockquote>
<pre><code class="language-cpp">template&lt;typename T, typename U&gt;
polynom&lt;T&gt; operator* (const polynom&lt;T&gt;&amp; lhs, const U&amp; rhs)
{
  polynom&lt;T&gt; ret_val(lhs);
  lhs *= rhs;
  return lhs;
}
</code></pre>
<p>Musst du nicht ret_val *= rhs nehmen, sonst überschreibst du doch einen Faktor oder nicht?</p>
</blockquote>
<p>Ja, natürlich - flüchtigkeitsfehler 4tw :&gt;</p>
<p>Andreas_L schrieb:</p>
<blockquote>
<p>Kann man das folgende wirklich so kompilieren - greifst du nicht auf private Variablen zu?</p>
<pre><code class="language-cpp">template&lt;typename U&gt;
  explicit polynom(const polynom&lt;U&gt;&amp; other)
  : coeff(other.coeff.size())
  {
    coeff_container::const_iterator j(other.coeff.begin());
    for(coeff_container::const i(coeff.begin()), e(coeff.end()); i != e; ++i, ++j)
      *i = static_cast&lt;value_type&gt;(*j);
  }
</code></pre>
</blockquote>
<p>Nein - welche sollen hier private sein?</p>
<p>den letzten post versteh ich nicht - ist mir zu verworren ;o)</p>
<p>und was soll ne determinante oder ne matrix mit nem polynom zu tun haben?<br />
vll sagst du mal, was du genau haben möchtest... (noch mal den post vorm abschicken durchlesen und gedanken zu ordnen kann auch sinn machen!)<br />
<code>CPolynom&amp; operator=(CPolynom&amp; AnderesPolynom);</code> hier fehlt z.bsp. nen const</p>
<pre><code class="language-cpp">template&lt;typename U&gt; 
CPolynom&amp; operator=(const U&amp; Zahl);
</code></pre>
<p>Sinn?<br />
<code>Polynom = 4;</code> und jetzt? Oo</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1853906</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1853906</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Wed, 10 Feb 2010 21:50:04 GMT</pubDate></item><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Wed, 10 Feb 2010 22:13:53 GMT]]></title><description><![CDATA[<p>Andreas_L schrieb:</p>
<blockquote>
<p>... Jetzt soll man das Polynom auch mit einer &quot;normalen Zahl&quot; multiplizieren können (short, int, Long, double, float) - hab die Methoden aber bisher nur für double implementiert und gemerkt, dass mein Compiler die Zahlen nicht einfach entsprechend castet ...</p>
</blockquote>
<p>Ok, ich rate mal. Dein Code sieht in etwa so aus:</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
poly&lt;T&gt; operator*(poly&lt;T&gt; const&amp; p, T factor)
{
  ...
}
</code></pre>
<p>und Du wunderst Dich, dass Du ein <code>poly&lt;double&gt;</code> nicht mit einem <code>int</code> multiplizieren kannst, richtig?</p>
<p>Nun, das liegt an der &quot;Template Argument Deduction&quot;. Es gibt hier zwei &quot;deduzierbare&quot; Kontexte, nämlich beide Parameter. Der Compiler vergleicht <code>poly&lt;double&gt;</code> mit <code>poly&lt;T&gt;</code> und kommt zum Ergebnis T=double. Dann vergleicht er für den zweiten Parameter <code>int</code> mit <code>T</code> und kommt zum Ergebnis T=int. Da das ein Widerspruch zum ersten Ergebnis ist, schlägt die &quot;Deduktion&quot; fehl und das Template wird ignoriert.</p>
<p>Mir fallen 3 Möglichkeiten ein, wie man das umgehen könnte.</p>
<p>1. So, wie es unskilled gezeigt hat, einen weiteren Template-Parameter einführen. Das könnte aber auch zu Code-Bloat führen (viele fast gleiche Funktionen).</p>
<p>2. Verwendung eines nicht-deduzierbaren Kontexts für den zweiten Parameter. Eine Konvertierung wird dann zugelassen.</p>
<pre><code class="language-cpp">template&lt;typename T&gt; struct identity {typedef T type;};

template&lt;typename T&gt;
poly&lt;T&gt; operator*(poly&lt;T&gt; const&amp; p,
  typename identity&lt;T&gt;::type factor)
{
  ...
}
</code></pre>
<p>3. Verwendung einer nicht-Template, inline, friend Funktion.</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
class poly
{
  ...
  friend poly operator*(poly const&amp; p, T factor)
  {
    ...
  }
  ...
};
</code></pre>
<p>Für jeden Typ <code>poly&lt;T&gt;</code> wird somit die Funktion <code>poly&lt;T&gt; operator*(poly&lt;T&gt; const&amp;,T)</code> bereitgestellt, welche durch <a href="http://de.wikipedia.org/wiki/Argument_dependent_name_lookup" rel="nofollow">ADL</a> gefunden werden kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1853909</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1853909</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Wed, 10 Feb 2010 22:13:53 GMT</pubDate></item><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Wed, 10 Feb 2010 22:27:28 GMT]]></title><description><![CDATA[<p>ok ich versuchs mal - für mich war das an sich klar^^</p>
<blockquote>
<p>Nein - welche sollen hier private sein?</p>
</blockquote>
<p>Du hast doch coeff als private deklariert - greifst nun aber einfach darauf zu:</p>
<pre><code class="language-cpp">other.coeff.begin());
</code></pre>
<blockquote>
<p>CPolynom&amp; operator=(CPolynom&amp; AnderesPolynom); hier fehlt z.bsp. nen const</p>
</blockquote>
<p>Zum const - das hab ich extra weggelassen weil es da irgendwie Probleme gab: Ich hab beim Polynom auch den []-Operator überladen um auf die Koeffizienten zugreifen zu können. Wenn ich jetzt aber oben ein const reinschreibe konnte ich den []-Operator nicht mehr ohne Compilerfehler verwenden.</p>
<blockquote>
<p>und was soll ne determinante oder ne matrix mit nem polynom zu tun haben?<br />
vll sagst du mal, was du genau haben möchtest...</p>
</blockquote>
<p>Ich weiß nicht ob du das kennst: Man kann für eine Matrix Eigenwerte und Eigenvektoren ausrechnen. Um die Eigenwerte zu bestimmen brauche ich die Determinante:<br />
Ich muss meine Matrix minus x* Einheitsmatrix nehmen - d.h. auf der Diagonalen steht jeweils nun zusätzlich ein -x. Von der resultierenden Matrix muss ich die Determinante ausrechnen. Das gibt dann ein Polynom n-ten Grades, wenn die Matrix eine nxn-Matrix ist. Die Nullstellen dieses Polynoms sind meine gesuchten Eigenwerte.</p>
<blockquote>
<p>Sinn?<br />
Polynom = 4; und jetzt? Oo</p>
</blockquote>
<p>Die Methode &quot;Determinante&quot; war urpsrünglich einfach nur für double geschrieben worden. Jetzt wollte ich aber nicht einfach alles neu schreiben sondern hab mir gedacht ich mache ein Template daraus. Das Polynom muss auf 0 gesetzt werden (d.h. einfach ein Polynom 0-ten Grades wobei der übrig gebliebene Koeffizient 0 ist), da später += verwendet wird (sonst habe ich ja ein nicht initialisiertes Polynom auf das ich addiere).</p>
<p>Ist das jetzt etwas klarer geworden - unabhängig davon ob du das mit Eigenwerten kennst oder nicht?</p>
<p>Was muss ich denn dann jetzt machen, damit der Zuweisungsoperator und nicht der Konstruktor verwendet wird?</p>
<p>Viele Grüße</p>
<p>Andreas</p>
<p>Sry Sebastian - war schon am formulieren als du deines abgeschickt hast. Muss zugeben das ich das Polynom gar nicht so variabel bisher gehalten hab. Bisher hab ich einfach double vorgeschrieben ohne Template. Kann das sein, dass deine zweite Möglichkeit dann nicht funktioniert (hab versucht das auf meinen Fall (kein Template) zu übertragen):</p>
<pre><code class="language-cpp">template&lt;typename T&gt; struct identity {typedef T type;}; 
CPolynom operator*(typename identity&lt;double&gt;::type &amp; Zahl, CPolynom&amp; Polynom);
</code></pre>
<p>aber da erhalte ich nur den Fehler &quot;error C2899: Der Typname kann nicht außerhalb einer Vorlagendeklaration verwendet werden&quot;.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1853910</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1853910</guid><dc:creator><![CDATA[Andreas_L]]></dc:creator><pubDate>Wed, 10 Feb 2010 22:27:28 GMT</pubDate></item><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Thu, 11 Feb 2010 02:38:26 GMT]]></title><description><![CDATA[<p>Mir war gerad langweilig - keine Ahnung, ob es dir hilft - aber so meinte ich das ganze und so wie es aussieht, klappt es auch ganz gut^^</p>
<p>Das mit dem Code-Bloat verstehe ich hier nicht ganz (mir ist bekannt, was das heißt - nur seh ich nicht, wo/wieso)...</p>
<p>Ansonsten gefällt mir nur die Warnung wegen der Addition unterschiedlicher Typen nicht so wirklich <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f623.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--persevering_face"
      title="&gt;.&lt;"
      alt="😣"
    /> sind (logischerweise) gleich 3 Warnungen wegen einer Zeile <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":/"
      alt="😕"
    /></p>
<p>der op+= sieht vll ein wenig chaotisch aus, aber soweit ich weiß, ist resize nicht exceptionsafe -&gt; brauchen kurzzeitig nen anderes array - und dann können wir auch gleich darauf arbeiten. das kann man aber definitv noch hübscher schreiben(z.bsp. mittels reserve + push_back statt des zusätzlichen iterators, etc.)</p>
<p>die test-ausgabe ist nicht gerade sehr c++ig oder elegant - aber um es richtig zu machen, fehlte mir dann doch die muse^^</p>
<pre><code class="language-cpp">#include &lt;iterator&gt;
#include &lt;numeric&gt;
#include &lt;vector&gt;

template&lt;typename T&gt;
struct polynom
{
	typedef T value_type;
	typedef std::size_t size_type;

	polynom()
	{}

	/* copy-ctor and assignment operator works fine for us */

	explicit polynom(size_type highest_exponent, value_type coeff = value_type())
	:	coeff( static_cast&lt;coeff_container::size_type&gt;(highest_exponent), coeff )
	{}

	template&lt;typename U&gt;
	explicit polynom(const polynom&lt;U&gt;&amp; other)
	:	coeff( other.coeff.size() )
	{
		typename polynom&lt;U&gt;::coeff_container::const_iterator j(other.coeff.begin());
		for(coeff_container::iterator i(coeff.begin()), e(coeff.end()); i != e; ++i, ++j)
			*i = static_cast&lt;value_type&gt;(*j);
	}

	size_type get_max_coeff() const
	{
		return static_cast&lt;size_type&gt;(coeff.size());
	}

	value_type&amp; get_coefficient(size_type exponent)
	{
		coeff_container::iterator i = coeff.begin();
		std::advance( i, static_cast&lt;coeff_container::size_type&gt;(exponent) );
		return *i;
	}
	const value_type&amp; get_coefficient(size_type exponent) const
	{
		coeff_container::const_iterator i = coeff.begin();
		std::advance( i, static_cast&lt;coeff_container::size_type&gt;(exponent) );
		return *i;
	}

	template&lt;typename U&gt;
	polynom&amp; operator+= (const polynom&lt;U&gt;&amp; other)
	{
		if(coeff.size() &lt; other.coeff.size())
		{
			coeff_container tmp(other.coeff.size());

			typename polynom&lt;U&gt;::coeff_container::const_iterator
				longer_i(other.coeff.begin()),
				longer_e(other.coeff.end());

			coeff_container::const_iterator shorter_i(coeff.begin()), shorter_e(coeff.end());

			coeff_container::iterator dest(tmp.begin());
			for(; shorter_i != shorter_e; ++shorter_i, ++ longer_i, ++dest)
				*dest = *shorter_i + *longer_i;

			for(; longer_i != longer_e; ++longer_i, ++dest)
				*dest = *longer_i;

			using std::swap;
			swap(coeff, tmp);
		}
		else
		{
			typename polynom&lt;U&gt;::coeff_container::const_iterator i(other.coeff.begin()), e(other.coeff.end());
			for(coeff_container::iterator dest(coeff.begin()); i != e; ++i, ++dest)
				*dest += *i;
		}

		return *this;
	}

	template&lt;typename U&gt;
	polynom&amp; operator+= (U skalar)
	{
		if(coeff.empty())
			coeff.push_back(skalar);
		else
			coeff.front() += skalar;

		return *this;
	}

private:
	typedef std::vector&lt;value_type&gt; coeff_container;
	coeff_container coeff;

	template&lt;typename&gt; friend struct polynom;
};

template&lt;typename T, typename U&gt;
polynom&lt;T&gt; operator+ (const polynom&lt;T&gt;&amp; lhs, const U&amp; rhs)
{
	polynom&lt;T&gt; ret_val(lhs);
	ret_val += rhs;
	return ret_val;
}

#include &lt;iostream&gt;

int main()
{
	polynom&lt;int&gt; a;           /* - */
	polynom&lt;float&gt; b(3, 2.f); /* 2 + 2x + 2x² */
	polynom&lt;double&gt; c(4, 3.); /* 3 + 3x + 3x² + 3x³*/

	polynom&lt;int&gt; a_copy(a);
	polynom&lt;int&gt; b_copy(b);
	polynom&lt;float&gt; b_plus_c( b + polynom&lt;float&gt;(c) );
	polynom&lt;float&gt; b_plus_b( b + b );
	polynom&lt;float&gt; c_plus_b( polynom&lt;float&gt;(c) + b );

	a = a + 3;
	a = a + polynom&lt;int&gt;(b);

	std::cout &lt;&lt; &quot;a: (5 / 2 / 2)&quot; &lt;&lt; &quot;\r\n&quot;;
	for(polynom&lt;int&gt;::size_type i(0), e(a.get_max_coeff()); i != e; ++i)
		std::cout &lt;&lt; a.get_coefficient(i) &lt;&lt; &quot; *x^&quot; &lt;&lt; i &lt;&lt; &quot;\r\n&quot;;
	std::cout &lt;&lt; std::endl;

	std::cout &lt;&lt; &quot;a_copy: (empty)&quot; &lt;&lt; &quot;\r\n&quot;;
	for(polynom&lt;int&gt;::size_type i(0), e(a_copy.get_max_coeff()); i != e; ++i)
		std::cout &lt;&lt; a_copy.get_coefficient(i) &lt;&lt; &quot; *x^&quot; &lt;&lt; i &lt;&lt; &quot;\r\n&quot;;
	std::cout &lt;&lt; std::endl;

	std::cout &lt;&lt; &quot;b: (2 / 2 / 2)&quot; &lt;&lt; &quot;\r\n&quot;;
	for(polynom&lt;float&gt;::size_type i(0), e(b.get_max_coeff()); i != e; ++i)
		std::cout &lt;&lt; b.get_coefficient(i) &lt;&lt; &quot; *x^&quot; &lt;&lt; i &lt;&lt; &quot;\r\n&quot;;
	std::cout &lt;&lt; std::endl;

	std::cout &lt;&lt; &quot;b_copy: (2 / 2 / 2)&quot; &lt;&lt; &quot;\r\n&quot;;
	for(polynom&lt;float&gt;::size_type i(0), e(b_copy.get_max_coeff()); i != e; ++i)
		std::cout &lt;&lt; b_copy.get_coefficient(i) &lt;&lt; &quot; *x^&quot; &lt;&lt; i &lt;&lt; &quot;\r\n&quot;;
	std::cout &lt;&lt; std::endl;

	std::cout &lt;&lt; &quot;c: (3 / 3 / 3 / 3)&quot; &lt;&lt; &quot;\r\n&quot;;
	for(polynom&lt;double&gt;::size_type i(0), e(c.get_max_coeff()); i != e; ++i)
		std::cout &lt;&lt; c.get_coefficient(i) &lt;&lt; &quot; *x^&quot; &lt;&lt; i &lt;&lt; &quot;\r\n&quot;;
	std::cout &lt;&lt; std::endl;

	std::cout &lt;&lt; &quot;b_plus_c: (5 / 5 / 5 / 3)&quot; &lt;&lt; &quot;\r\n&quot;;
	for(polynom&lt;float&gt;::size_type i(0), e(b_plus_c.get_max_coeff()); i != e; ++i)
		std::cout &lt;&lt; b_plus_c.get_coefficient(i) &lt;&lt; &quot; *x^&quot; &lt;&lt; i &lt;&lt; &quot;\r\n&quot;;
	std::cout &lt;&lt; std::endl;

	std::cout &lt;&lt; &quot;b_plus_b: (4 / 4 / 4)&quot; &lt;&lt; &quot;\r\n&quot;;
	for(polynom&lt;float&gt;::size_type i(0), e(b_plus_b.get_max_coeff()); i != e; ++i)
		std::cout &lt;&lt; b_plus_b.get_coefficient(i) &lt;&lt; &quot; *x^&quot; &lt;&lt; i &lt;&lt; &quot;\r\n&quot;;
	std::cout &lt;&lt; std::endl;

	std::cout &lt;&lt; &quot;c_plus_b: (5 / 5 / 5 / 3)&quot; &lt;&lt; &quot;\r\n&quot;;
	for(polynom&lt;float&gt;::size_type i(0), e(c_plus_b.get_max_coeff()); i != e; ++i)
		std::cout &lt;&lt; c_plus_b.get_coefficient(i) &lt;&lt; &quot; *x^&quot; &lt;&lt; i &lt;&lt; &quot;\r\n&quot;;
	std::cout &lt;&lt; std::endl;

	polynom&lt;int&gt; warn_me_pls;
	warn_me_pls += polynom&lt;float&gt;();
}
</code></pre>
<p>Jz zu deinen Fragen:</p>
<blockquote>
<p>Du hast doch coeff als private deklariert - greifst nun aber einfach darauf zu</p>
</blockquote>
<p>Jopp, friend vergessen - dabei war ich mir so sicher, dass ich es hingeschrieben hatte <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f623.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--persevering_face"
      title="&gt;.&lt;"
      alt="😣"
    /></p>
<blockquote>
<p>hab beim Polynom auch den []-Operator überladen um auf die Koeffizienten zugreifen zu können.</p>
</blockquote>
<p>ich hoffe einen []op const und einen non-const!?</p>
<blockquote>
<p>Ich weiß nicht ob du das kennst: <em>[Eigenwerte, ...]</em></p>
</blockquote>
<p>Jopp - aber ich wüsste nicht, was das hier interessieren sollte bei deinem Problem - es ging dir ja nur darum, ob assignment-op oder copy-ctor aufgerufen werden - da ist die aufgabe doch völlig nebensächlich... (und da du lieber die aufgabe beschrieben hast anstatt nen stück aussagekräftigen code und genaue beschreibung zu posten, weiß ich auch noch immer nicht, wo dein problem liegt)</p>
<blockquote>
<p>aber da erhalte ich nur den Fehler</p>
</blockquote>
<p>Klingt so, als ob dein polynom kein template ist und du das typename trotzdem mitgeschrieben hast - das wäre nur bei templates wichtig...</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1853965</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1853965</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Thu, 11 Feb 2010 02:38:26 GMT</pubDate></item><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Thu, 11 Feb 2010 09:36:23 GMT]]></title><description><![CDATA[<p>Andreas_L schrieb:</p>
<blockquote>
<p>...</p>
</blockquote>
<p>Verrat doch erstmal, was Du überhaupt machen willst (nicht wie, sondern was).</p>
<p>Sag dann, was Du Dir für eine Lösung überlegt hast (Ansatz)</p>
<p>Zeig dann ein bissel Code. (Implementierung)</p>
<p>Wenn's darum geht Eigenwerte zu bestimmen, dafür gibt es ganz andere Algorithmen, die sich nicht mit Polynomen rumärgern. Eigenwerte über Nullstellen zu berechnen ist der falsche Ansatz -- zumindest wenn Du Matritzen mit mehr als 2x2 Elementen arbeitest. Das Nullstellen-Problem ist viel schwieriger. Im Gegenteil: Es gibt Nullstellen-Löser, die das Problem auf ein Eigenwertproblem reduzieren.</p>
<p>Eigenwerte einer Matrix &quot;vernünftig&quot; berechnen ist aber trotzdem noch nicht so einfach. Da nimmt man am besten eine Numerik-Bibliothek, die das kann. Du solltest auch wissen, dass es für versch Matrixtypen versch spezialisierte Algorithmen gibt. Eigenwerte für symmetrische Matrizen zu berechnen, kann man Normalsterblichen noch zumuten. Alles andere ist schwarze Magie, die man auch nach einem Mathematikstudium wieder vergessen hat -- es sei denn, man hat sich auf so etwas spezialisiert. (!!!)</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1854046</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1854046</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Thu, 11 Feb 2010 09:36:23 GMT</pubDate></item><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Thu, 11 Feb 2010 14:22:46 GMT]]></title><description><![CDATA[<p>Hallo, erstmal vielen Dank für eure Bemühungen.</p>
<blockquote>
<p>Wenn's darum geht Eigenwerte zu bestimmen, dafür gibt es ganz andere Algorithmen, die sich nicht mit Polynomen rumärgern. Eigenwerte über Nullstellen zu berechnen ist der falsche Ansatz -- zumindest wenn Du Matritzen mit mehr als 2x2 Elementen arbeitest. Das Nullstellen-Problem ist viel schwieriger. Im Gegenteil: Es gibt Nullstellen-Löser, die das Problem auf ein Eigenwertproblem reduzieren.</p>
<p>Eigenwerte einer Matrix &quot;vernünftig&quot; berechnen ist aber trotzdem noch nicht so einfach. Da nimmt man am besten eine Numerik-Bibliothek, die das kann. Du solltest auch wissen, dass es für versch Matrixtypen versch spezialisierte Algorithmen gibt. Eigenwerte für symmetrische Matrizen zu berechnen, kann man Normalsterblichen noch zumuten. Alles andere ist schwarze Magie, die man auch nach einem Mathematikstudium wieder vergessen hat -- es sei denn, man hat sich auf so etwas spezialisiert. (!!!)</p>
</blockquote>
<p>Ich weiß das das für große Matrizen eine riesige Laufzeit verursacht. Ich hab nur gerade diese Möglichkeit im Studium gelernt und möchte die gerne umsetzen und zwar hobbymäßig um damit Differentialgleichungssysteme zu lösen. Ich hab bei Wikipedia auch Alternativen gelesen, die für große Matrizen sehr viel schneller sind, aber die verstehe ich ja noch nicht - ich möchte einfach mal das Programmtechnisch umsetzen, was ich bisher gelernt habe.</p>
<p>Und nun zum Code - ich hab kein Template fürs Polynom genommen und auch keinen Vector für die Koeffizienten - deshalb sieht mein Code etwas anders aus:</p>
<p>Die Klassenübersicht fürs Polynom:</p>
<pre><code class="language-cpp">class CPolynom
{
protected:
	unsigned short	m_iGrad;				//Grad des Polynoms
	double*			m_pKoeffizienten;		//Koeffizienten des Polynoms - Koeffizienten[n] entspricht dem Koeffizienten vor x^n.

public:
	CPolynom(unsigned short Grad);
	CPolynom(void);
	double&amp; operator[](unsigned short i);

	~CPolynom(void);

	CPolynom(CPolynom&amp; AnderesPolynom); 
	CPolynom&amp; operator=(CPolynom&amp; AnderesPolynom); 

	template&lt;typename U&gt; 
	CPolynom&amp; operator=(const U&amp; Zahl); 

	CPolynom&amp; operator+=(CPolynom&amp; AnderesPolynom);
	CPolynom&amp; operator-=(CPolynom&amp; AnderesPolynom);

	template&lt;typename U&gt; 
	CPolynom&amp; operator*=(const U&amp; Zahl);
	CPolynom&amp; operator*=(CPolynom&amp; AnderesPolynom);
	template&lt;typename U&gt; 
	CPolynom&amp; operator/=(const U&amp; Zahl);
	template&lt;typename U&gt; 
	bool operator==(const U&amp; Zahl);

	unsigned short GetGrad();					//Liefert den Grad des Polynoms
	void Koeffizienten_leeren();				//Alle Koeffizienten auf 0 setzen

};

CPolynom operator-(CPolynom&amp; Minuend, CPolynom&amp; Subtrahend);
CPolynom operator+(CPolynom&amp; summand1, CPolynom&amp; summand2);
template&lt;typename U&gt; 
CPolynom operator*(U&amp; Zahl, CPolynom&amp; Polynom);
template&lt;typename U&gt; 
CPolynom operator*(CPolynom&amp; Polynom, U&amp; Zahl);
template&lt;typename U&gt; 
CPolynom operator/(CPolynom&amp; Polynom, U&amp; Zahl);
CPolynom operator*(CPolynom&amp; Polynom1, CPolynom&amp; Polynom2);

std::ostream&amp; operator&lt;&lt;(std::ostream&amp; stream, CPolynom&amp; obj);
</code></pre>
<blockquote>
<p>ich hoffe einen []op const und einen non-const!?</p>
</blockquote>
<p>Bisher nicht - wollte es erstmal erreichen das es funktioniert - danach kommt &quot;Kosmetik&quot;.<br />
Ich weiß nicht genau welche Methoden euch interessieren - ich poste mal ein paar:</p>
<pre><code class="language-cpp">CPolynom::CPolynom(unsigned short Grad)
{
	assert(Grad &gt;= 0);

	m_iGrad = Grad;
	m_pKoeffizienten = new double[Grad+1];
}

CPolynom::CPolynom()
{
	m_iGrad = 0;
	m_pKoeffizienten = new double[1];
	m_pKoeffizienten[0] = 0.0;
}	

CPolynom::~CPolynom(void)
{
	delete[] m_pKoeffizienten;
}
template&lt;typename U&gt; 
CPolynom&amp; CPolynom::operator=(const U&amp; Zahl)
{
	if(m_iGrad != 0)
	{
		delete[] m_pKoeffizienten;
		m_iGrad = 0;
		m_pKoeffizienten = new double[m_iGrad+1];
	}

	m_pKoeffizienten[0] = Zahl;

	return *this;
}
</code></pre>
<p>Die Additionsmethode sieht bei mir etwas anders aus - schließlich will ich ein Array haben, dass vor dem X mit dem höchsten Exponenten einen Koeffizienten != 0 hat - sonst wäre die Gradangabe ja auch falsch.</p>
<pre><code class="language-cpp">CPolynom&amp; CPolynom::operator+=(CPolynom&amp; AnderesPolynom)
{
	if(m_iGrad == AnderesPolynom.GetGrad()) //Wenn z.B. 3x^2+2x + (-3x^2-2x) gerechnet wird ist der Grad der Funktion danach nciht mehr 2
	{
		unsigned short counter = 0;

		for(short i = m_iGrad; i &gt;= 0; i--)
		{
			if(AnderesPolynom[i] == -m_pKoeffizienten[i]) counter++;
			else break;
		}

		if(counter == 0)
		{
			for(unsigned short i = 0; i &lt;= m_iGrad; i++)
			{
				m_pKoeffizienten[i]+=AnderesPolynom[i];
			}
		}
		else
		{
			double* Neuekoeffizienten =  new double[m_iGrad+1-counter];

			for(unsigned short i = 0; i &lt;= m_iGrad-counter; i++)
			{
				Neuekoeffizienten[i] = m_pKoeffizienten[i]+AnderesPolynom[i];
			}
			delete[] m_pKoeffizienten;
			m_pKoeffizienten = Neuekoeffizienten;
			m_iGrad -= counter;
		}
	}
	else if(m_iGrad &gt; AnderesPolynom.GetGrad())
	{
		for(unsigned short i = 0; i &lt;= AnderesPolynom.GetGrad(); i++)
		{
			m_pKoeffizienten[i]+=AnderesPolynom[i];
		}
	}
	else //AnderesPolynom.GetGrad() &gt; m_iGrad
	{
		double* Neuekoeffizienten =  new double[AnderesPolynom.GetGrad()+1];

		for(unsigned short i = 0; i &lt;= m_iGrad; i++)
		{
			Neuekoeffizienten[i] = m_pKoeffizienten[i]+AnderesPolynom[i];
		}
		for(unsigned short i = m_iGrad+1; i &lt;= AnderesPolynom.GetGrad(); i++)
		{
			Neuekoeffizienten[i] = AnderesPolynom[i];
		}
		delete[] m_pKoeffizienten;
		m_pKoeffizienten = Neuekoeffizienten;
		m_iGrad = AnderesPolynom.GetGrad();
	}

	return *this;
}
</code></pre>
<p>So und nun die problematische Methode, in der die Determinante berechnet wird:</p>
<pre><code class="language-cpp">template &lt;class Datentyp&gt;
Datentyp CMatrix&lt;Datentyp&gt;::Determinante_Rekursiv()
{

	unsigned short List_Groesse = m_Matrix_Ersatz.size();

	if(List_Groesse == 2) //für den Rekursionsabbruch bei 2
	{
		std::list&lt;Datentyp*&gt;::iterator Iter1 = m_Matrix_Ersatz.begin();
		std::list&lt;Datentyp*&gt;::iterator Iter2 = Iter1; Iter2++;
		return ((*Iter1)[m_iDimension-2]*(*Iter2)[m_iDimension-1]-(*Iter1)[m_iDimension-1]*(*Iter2)[m_iDimension-2]);
	}

	Datentyp Unterdeterminante = 0;
	Datentyp* Zeile;	//aktuell herausgenommene Zeile

	if(List_Groesse &amp; 1) //ungerade - durch das Verändern der Matrix ergibt sich immer das passende Vorzeichen.
	{
		for(unsigned int index = 0; index &lt; List_Groesse; index++)
		{
			Zeile = m_Matrix_Ersatz.front();
			m_Matrix_Ersatz.pop_front();
			Unterdeterminante += Zeile[m_iDimension-List_Groesse]*Determinante_Rekursiv();;
			m_Matrix_Ersatz.push_back(Zeile);
		}

	}//end of if
	else //gerade - hier ändert das Verändern der Matrix an der Determinante nichts, deshalb wird das Vorzeichen benötigt.
	{	
		short Vorzeichen = 1;
		for(unsigned int index = 0; index &lt; List_Groesse; index++)
		{
			Zeile = m_Matrix_Ersatz.front();
			m_Matrix_Ersatz.pop_front();
			Unterdeterminante += Vorzeichen*Zeile[m_iDimension-List_Groesse]*Determinante_Rekursiv();
			m_Matrix_Ersatz.push_back(Zeile);

			Vorzeichen *= -1;
		}
	}//end of else

	return Unterdeterminante;
}//end of Determinante_Rekursiv
</code></pre>
<p>Sie mag vielleicht etwas komisch aussehen: Die Determinante wird nach Spalten entwickelt. Jetzt fand ich das aber sehr ineffizient jedesmal für die Unterdeterminante die Teilmatrix zu kopieren, deshalb hab ich die Zeilen in einer Liste angeordnet, wobei ich dann eben immer entsprechend die Zeile für die Berechnung der Unterdeterminante herausnehmen kann.<br />
Der Code funktioniert für double - das hab ich ausprobiert, allerdings gibts probleme bei</p>
<p>Datentyp Unterdeterminante = 0;</p>
<p>für die Polynome, da hier nicht mein Zuweisungsoperator sondern der Konstruktor des Polynoms mit dem Wert 0 für Grad aufgerufen wird.</p>
<p>Hab ich was wichtiges vergessen zu sagen?</p>
<p>Viele Grüße</p>
<p>Andreas</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1854212</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1854212</guid><dc:creator><![CDATA[Andreas_L]]></dc:creator><pubDate>Thu, 11 Feb 2010 14:22:46 GMT</pubDate></item><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Fri, 12 Feb 2010 08:51:16 GMT]]></title><description><![CDATA[<p>Andreas_L schrieb:</p>
<blockquote>
<p>Ich weiß das das für große Matrizen eine riesige Laufzeit verursacht.</p>
</blockquote>
<p>Nicht nur das. Nullstellen von Polynomen höheren Grades auszurechnen ist auch numerisch sehr schlecht, besonders bei mehrfachen Nullstellen (ganz ganz böse!).</p>
<p>Andreas_L schrieb:</p>
<blockquote>
<p>Ich hab nur gerade diese Möglichkeit im Studium gelernt und möchte die gerne umsetzen und zwar hobbymäßig</p>
</blockquote>
<p>Wieso? Kannst Du jetzt nicht mehr lernen?</p>
<p>Andreas_L schrieb:</p>
<blockquote>
<p>um damit Differentialgleichungssysteme zu lösen. Ich hab bei Wikipedia auch Alternativen gelesen, die für große Matrizen sehr viel schneller sind,</p>
</blockquote>
<p>schneller und überhaupt numerisch viel besser (Genauigkeit!).</p>
<p>Andreas_L schrieb:</p>
<blockquote>
<p>Die Klassenübersicht fürs Polynom:</p>
<pre><code class="language-cpp">...
</code></pre>
</blockquote>
<p>Nimm std::vector&lt;double&gt; für die Koeffizienten. Dann brauchst Du Dich auch nicht mehr so sehr um die Speicherverwaltung kümmern. Du brauchst dann keinen eigenen Kopierkonstruktor, Zuweisung, Destruktor. Du machst es Dir echt unnötig schwer.</p>
<p>Lass das mit den Templates sein. Typparameter U brauchst Du doch nicht. Nimm doch einfach double.</p>
<p>Andreas_L schrieb:</p>
<blockquote>
<pre><code class="language-cpp">CPolynom&amp; CPolynom::operator+=(CPolynom&amp; AnderesPolynom)
{
  ...
}
</code></pre>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /><br />
Viel zu kompliziert! Du hast auch ein const beim Parameter vergessen. Es kann doch soooo schön einfach sein:</p>
<pre><code class="language-cpp">class Polynom
{
  std::vector&lt;double&gt; koeffs; // p(x) = Summe_i koeffs[i]*x^i
public:
  ...
  double operator()(double x) const;
  ...
  Polynom&amp; operator+=(Polynom const&amp; p);
  ...
};

double Polynom::operator()(double x) const
{
  double acc = 0;  // &quot;Akkumulator&quot;
  for (int i=koeffs.size(); i-- &gt;0;) {
    acc = acc * x + koeffs[i];
  }
  return acc;
}

Polynom&amp; Polynom::operator+=(Polynom const&amp; p)
{
  koeffs.resize( std::max(koeffs.size(),p.koeffs.size()) , 0.0 );
  for (int i=0, e=p.koeffs.size(); i&lt;e; ++i) {
    koeffs[i] += p.koeffs[i];
  }
  while (koeffs.size()&gt;0u &amp;&amp; koeffs.back()==0) {
    koeffs.pop_back();
  }
}
</code></pre>
<p>Andreas_L schrieb:</p>
<blockquote>
<p>So und nun die problematische Methode, in der die Determinante berechnet wird:</p>
<pre><code class="language-cpp">...
</code></pre>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /><br />
Das ist so ziemlich das schlechteste, was man machen kann, um Determinanten zu berechnen. Ich finde immer noch den Ansatz über die Determinante mit Polynomen sehr schlecht -- nur dass das klar ist. Aber Determinanten berechnet man ganz anders. Wenn man die wirklich berechnen will, transformiert man die Matrix in eine Dreiecksmatrix, merkt sich dabei, wie viele Zeilen- bzw. Spaltenvertauschungen man gemacht (k), berechnet das Produkt der Diagonalen und multipliziert dieses mit (-1)^k. Fertig. Das geht ratzfatz in O(n^3). Mit &quot;transfomieren&quot; meine ich die Operationen, die man auch für's Lösen eines Gleichungssystems durchführen würde, also zB Zeilen vertauschen und ein Vielfaches einer Zeile auf eine andere addieren. Ersteres negiert die Determinante. Leteres verändert die Determinante nicht. Die Determinante einer Dreiecksmatrix ist gleich dem Produkt der Elemente der Diagonalen, wenn ich mich nicht irre.</p>
<p>BTW: Es sollen schon Leute aus'm Job gefeuert worden sein, weil sie Determinanten von Matrizen über die Zeilen/Spaltenentwicklung berechnet haben -- sagte zumindest mein Numerik-Professor.</p>
<p>Edit: Stopp mal ... Du hast ja dann Polynome in der Matrix stehen. Dann macht das mit den Dreiecksmatrizen nicht viel Sinn. Du bräuchtest dann nämlich eine Division von Polynomen. Solche Polynome ergeben allerdings keinen algebraischen Körper. Wow! Willst Du nicht doch lieber das Eigenwertproblem richtig lösen lassen?</p>
<p>Andreas_L schrieb:</p>
<blockquote>
<p>Sie mag vielleicht etwas komisch aussehen: Die Determinante wird nach Spalten entwickelt. Jetzt fand ich das aber sehr ineffizient jedesmal für die Unterdeterminante die Teilmatrix zu kopieren, deshalb hab ich die Zeilen in einer Liste angeordnet, wobei ich dann eben immer entsprechend die Zeile für die Berechnung der Unterdeterminante herausnehmen kann.<br />
Der Code funktioniert für double - das hab ich ausprobiert, allerdings gibts probleme bei</p>
<p>Datentyp Unterdeterminante = 0;</p>
<p>für die Polynome, da hier nicht mein Zuweisungsoperator sondern der Konstruktor des Polynoms mit dem Wert 0 für Grad aufgerufen wird.</p>
</blockquote>
<p>Logisch. Es ist ja auch eine Initialisierung und keine Zuweisung. Wenn Du Polynom so definierst</p>
<pre><code class="language-cpp">class Polynom
{
  std::vector&lt;double&gt; koeffs;
public:
  ...
  // Schneller Default-Ctor (Nullpolynom)
  Polynom() {}

  // Konvertierungskonstruktor double-&gt;Polynom
  Polynom(double c) : koeffs(1) { koeffs[0]=c; }
  ...
};
</code></pre>
<p>dann klappt auch folgendes:</p>
<pre><code class="language-cpp">Polynom p = Polynom();
Polynom p = 0;          // &lt;--sogar auch das hier
</code></pre>
<p>Fazit: Es lohnt sich, das Problem zu erklären, was man lösen will -- besonders dann, wenn einem viel bessere Lösungswege aufgezeigt werden.</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1854246</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1854246</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Fri, 12 Feb 2010 08:51:16 GMT</pubDate></item><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Thu, 11 Feb 2010 16:11:37 GMT]]></title><description><![CDATA[<p>Hi Sebastian, vielen Dank für deine Erklärungen.</p>
<blockquote>
<p>Ich hab nur gerade diese Möglichkeit im Studium gelernt und möchte die gerne umsetzen und zwar hobbymäßig</p>
<p>Wieso? Kannst Du jetzt nicht mehr lernen?</p>
</blockquote>
<p>Ja schon - aber wenn ich mich noch in die Numeric reinknie brauche ich noch viel mehr Zeit, die ich nicht habe - ich studiere nämlich auch kein Informatik oder Mathematik sondern Physik und hab deshalb mit Numeric zumindest im Moment noch gar nichts zutun. Klar ist das schon sehr interessant zu verstehen wie diese numerischen Lösungen funktionieren - aber ich bin schon zufrieden wenn ich ein Programm schreiben kann, mit dem ich kleinere DGL-Sysmte lösen kann <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<blockquote>
<p>Lass das mit den Templates sein. Typparameter U brauchst Du doch nicht. Nimm doch einfach double.</p>
</blockquote>
<p>Wie darf ich das verstehen - schließlich war das ja mein Problem warum ich überhaupt zuerst ein Post erstellt habe. Wenn ich einfach nur double nehme gibts ja Probleme wenn ich das Polynom mit nem short multipliziere.</p>
<blockquote>
<p>Edit: Stopp mal ... Du hast ja dann Polynome in der Matrix stehen. Dann macht das mit den Dreiecksmatrizen nicht viel Sinn. Du bräuchtest dann nämlich eine Division von Polynomen. Solche Polynome ergeben allerdings keinen algebraischen Körper. Wow! Willst Du nicht doch lieber das Eigenwertproblem richtig lösen lassen?</p>
</blockquote>
<p>Genau deshalb hab ich die langsame Methode gewählt - weil ich nicht wusste wie ich mit der Division durch Polynome umgehen soll.</p>
<pre><code class="language-cpp">Polynom&amp; Polynom::operator+=(Polynom const&amp; p)
{
  koeffs.resize( std::max(koeffs.size(),p.koeffs.size()) , 0.0 );
  for (int i=0, e=koeffs.size(); i&lt;e; ++i) {
    koeffs[i] += p.koeffs[i];
  }
  while (koeffs.size()&gt;0u &amp;&amp; koeffs.back()==0) {
    koeffs.pop_back();
  }
}
</code></pre>
<p>Stimmt, ist wirklich wesentlich kürzer - aber mich stört dabei, dass der Vector erst vergrößert und dann nach und nach immer wieder verkleinert wird. Muss der Vector dann nicht häufig seinen ganzen Speicherbereich kopieren um sich der neuen Größe anzupassen? Bei mir ist nur eine Neuanpassung notwendig.</p>
<blockquote>
<p>Logisch. Es ist ja auch eine Initialisierung und keine Zuweisung. Wenn Du Polynom so definierst...</p>
</blockquote>
<p>Ok so funktionierts, aber wie kann ich das verstehen - warum ist das keine Zuweisung?<br />
Wenn ich das so mache gibts aber ein weiteres Problem meiner Ansicht nach:<br />
Ich wollte ja bisher einmal im Konstruktor den Grad übergeben bekommen, damit das Polynom initialisiert wird und dann über den []-Operator gefüllt werden kann. Jetzt hätte ich dann aber 2 Konstruktoren, die beide Zahlen annehmen. Zwar ist das einmal double und einmal short aber kann das nicht zu Problemen führen - sodass der falsche Konstruktor aufgerufen wird?<br />
Sobald doch schon einer schreibt Polynom(3) würde doch der short-Konstruktor aufgerufen - obwohl es an sich auch eine Initialisierung mit 3 als Wert (double Konstruktor) vom Programmierer gemeint sein könnte.</p>
<p>Viele Grüße</p>
<p>Andreas</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1854274</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1854274</guid><dc:creator><![CDATA[Andreas_L]]></dc:creator><pubDate>Thu, 11 Feb 2010 16:11:37 GMT</pubDate></item><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Thu, 11 Feb 2010 16:59:39 GMT]]></title><description><![CDATA[<p>Andreas_L schrieb:</p>
<blockquote>
<p>Hi Sebastian, vielen Dank für deine Erklärungen.</p>
<blockquote>
<p>Wieso? Kannst Du jetzt nicht mehr lernen?</p>
</blockquote>
<p>Ja schon - aber wenn ich mich noch in die Numeric reinknie brauche ich noch viel mehr Zeit, die ich nicht habe</p>
</blockquote>
<p>Deswegen nimmt man sich dafür auch eine Bibliothek, wie zB <a href="http://www.gnu.org/software/gsl/" rel="nofollow">GSL</a> oder so etwas in der Richtung.</p>
<p>Andreas_L schrieb:</p>
<blockquote>
<blockquote>
<p>Lass das mit den Templates sein. Typparameter U brauchst Du doch nicht. Nimm doch einfach double.</p>
</blockquote>
<p>Wie darf ich das verstehen - schließlich war das ja mein Problem warum ich überhaupt zuerst ein Post erstellt habe. Wenn ich einfach nur double nehme gibts ja Probleme wenn ich das Polynom mit nem short multipliziere.</p>
</blockquote>
<p>Ich weiß nicht, was Du für ein Problem hattest. Du hast es nicht gezeigt und ich habe anscheinend falsch geraten. Jedenfalls macht bei Deiner Polynom-Version es keinen Sinn, Den Typ von &quot;skalaren Operanden&quot; zu parameterisieren, wo Du doch double Werte für die Koeffizienten des Polynoms speicherst.</p>
<p>Andreas_L schrieb:</p>
<blockquote>
<blockquote>
<p>Edit: Stopp mal ... Du hast ja dann Polynome in der Matrix stehen. [...]</p>
</blockquote>
<p>Genau deshalb hab ich die langsame Methode gewählt - weil ich nicht wusste wie ich mit der Division durch Polynome umgehen soll.</p>
</blockquote>
<p>Dann ist ja gut, dass ich das mit den schlauen Numerik-Bibliotheken jetzt schon bestimmt 3mal erwähnt habe. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":-)"
      alt="🙂"
    /></p>
<p>Andreas_L schrieb:</p>
<blockquote>
<pre><code class="language-cpp">Polynom&amp; Polynom::operator+=(Polynom const&amp; p)
{
  koeffs.resize( std::max(koeffs.size(),p.koeffs.size()) , 0.0 );
  for (int i=0, e=koeffs.size(); i&lt;e; ++i) {
    koeffs[i] += p.koeffs[i];
  }
  while (koeffs.size()&gt;0u &amp;&amp; koeffs.back()==0) {
    koeffs.pop_back();
  }
}
</code></pre>
<p>Stimmt, ist wirklich wesentlich kürzer - aber mich stört dabei, dass der Vector erst vergrößert und dann nach und nach immer wieder verkleinert wird. Muss der Vector dann nicht häufig seinen ganzen Speicherbereich kopieren um sich der neuen Größe anzupassen? Bei mir ist nur eine Neuanpassung notwendig.</p>
</blockquote>
<p>1. Dass koeffs.back()==0 zutrifft ist höchst unwahrscheinlich, findest Du nicht? Ich habe die letzte Schleife nur Dir zuliebe eingefügt. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";-)"
      alt="😉"
    /><br />
2. pop_back() kostet fast nichts. Die Komplexitätsgarantie ist O(1). Da wird nichts umkopiert.</p>
<p>Andreas_L schrieb:</p>
<blockquote>
<blockquote>
<p>Logisch. Es ist ja auch eine Initialisierung und keine Zuweisung. Wenn Du Polynom so definierst...</p>
</blockquote>
<p>Ok so funktionierts, aber wie kann ich das verstehen - warum ist das keine Zuweisung?</p>
</blockquote>
<p><code>Typ Variable = Initialisierer;</code><br />
nennt sich &quot;copy initialization&quot; und kann in schlauen Büchern nachgelesen werden. Eine Zuweisung kann nur schon existierenden Objekten etwas zuweisen. Es wird hier auch nirgens ein Default-Konstructor aufgerufen, falls Du das denkst. Das sind die Regeln und das ist gut so (tm).</p>
<p>Andreas_L schrieb:</p>
<blockquote>
<p>Wenn ich das so mache gibts aber ein weiteres Problem meiner Ansicht nach:<br />
Ich wollte ja bisher einmal im Konstruktor den Grad übergeben bekommen, damit das Polynom initialisiert wird und dann über den []-Operator gefüllt werden kann. Jetzt hätte ich dann aber 2 Konstruktoren, die beide Zahlen annehmen. Zwar ist das einmal double und einmal short aber kann das nicht zu Problemen führen - sodass der falsche Konstruktor aufgerufen wird?</p>
</blockquote>
<p>Ja, da musst Du dich schon entscheiden. Bedenke, dass wenn Du eine implizite Konvertierung von double-&gt;Polynom hast, und nur die Operationen + - * auf Polynomen implementierst, dass Du dann auch automatisch mit Skalaren rechnen kannst. Also, bei &quot;meinpolynom * meindouble&quot; würde dann meindouble zu polynom konvertiert und dann mit dem ersten multipliziert. Toll wa? -- Natürlich kann man mit extra Overloads für double noch etwas Geschwindigkeit rausholen...</p>
<p>Andreas_L schrieb:</p>
<blockquote>
<p>Sobald doch schon einer schreibt Polynom(3) würde doch der short-Konstruktor aufgerufen - obwohl es an sich auch eine Initialisierung mit 3 als Wert (double Konstruktor) vom Programmierer gemeint sein könnte.</p>
</blockquote>
<p>Ja, is Käse. Aber ich weiß jetzt auch, was Dein ürsprüngliches Problem war. Du hattest ja schon einen Konvertierungkonstruktor short ---&gt; CPolynom, der gar keiner hätte sein dürfen! Deswegen gibt es in C++ auch das Schlüsselwort <code>explicit</code> .</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1854294</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1854294</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Thu, 11 Feb 2010 16:59:39 GMT</pubDate></item><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Thu, 11 Feb 2010 18:07:44 GMT]]></title><description><![CDATA[<p>Hi Sebastian,</p>
<p>nochmals danke für deine Erklärungen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":-)"
      alt="🙂"
    /></p>
<blockquote>
<p>Dann ist ja gut, dass ich das mit den schlauen Numerik-Bibliotheken jetzt schon bestimmt 3mal erwähnt habe. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":-)"
      alt="🙂"
    /></p>
</blockquote>
<p>Ja klar - aber die Sache ist doch das ich das freiwillig hobbymäßig selbst implementieren will um dabei auch besser zu lernen wie man mit so Problemen umgeht. Z.B. war mir bis heute noch nicht die Bedeutung von &quot;explicit&quot; bewusst, bzw. ich hab nie einen Sinn in diesem Schlüsselwort gesehen.</p>
<p>Es gibt wahrscheinlich auch Bibliotheken, die mir direkt die Eigenwerte ausgeben (oder gleich die DGL lösen) - aber dann kann ich auch direkt ein fertiges Matheprogramm nehmen, dann brauche ich nichts selber machen.</p>
<p>Es ist zwar nicht so produktiv aber ich mache das ja auch nicht um am Ende ein Programm zu haben das ich dauernd verwenden will - ich mache das eigentlich nur um während des Programmierens zu lernen.</p>
<p>Viele Grüße</p>
<p>Andreas</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1854324</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1854324</guid><dc:creator><![CDATA[Andreas_L]]></dc:creator><pubDate>Thu, 11 Feb 2010 18:07:44 GMT</pubDate></item><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Thu, 11 Feb 2010 18:49:16 GMT]]></title><description><![CDATA[<blockquote>
<p>Das ist so ziemlich das schlechteste, was man machen kann, um Determinanten zu berechnen. Ich finde immer noch den Ansatz über die Determinante mit Polynomen sehr schlecht -- nur dass das klar ist. Aber Determinanten berechnet man ganz anders. Wenn man die wirklich berechnen will, transformiert man die Matrix in eine Dreiecksmatrix, merkt sich dabei, wie viele Zeilen- bzw. Spaltenvertauschungen man gemacht (k), berechnet das Produkt der Diagonalen und multipliziert dieses mit (-1)^k. Fertig. Das geht ratzfatz in O(n^3). Mit &quot;transfomieren&quot; meine ich die Operationen, die man auch für's Lösen eines Gleichungssystems durchführen würde, also zB Zeilen vertauschen und ein Vielfaches einer Zeile auf eine andere addieren. Ersteres negiert die Determinante. Leteres verändert die Determinante nicht. Die Determinante einer Dreiecksmatrix ist gleich dem Produkt der Elemente der Diagonalen, wenn ich mich nicht irre.</p>
</blockquote>
<p>Jap, du irrst nicht. Ist afaik die effizienteste Methode.<br />
Habe mal nachgeschaut und die Methode soll 1/3n^3 Additionen und Multiplikationen bringen und die nach der üblichen Definition der Determinante (über Permutationen) hat n! Additionen und (n-1)n! Multiplikationen, was sehr extrem wird. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<blockquote>
<p>BTW: Es sollen schon Leute aus'm Job gefeuert worden sein, weil sie Determinanten von Matrizen über die Zeilen/Spaltenentwicklung berechnet haben -- sagte zumindest mein Numerik-Professor.</p>
</blockquote>
<p>Glaube ich gerne. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /> - Habe das mal für ne Übung in Matlab (resp. Octave) implementiert. Ich will mir gar nicht vorstellen, was da für Rekursionen zu Stande kommen für ne 100x100 Matrix. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /><br />
Vor allem ist die Methode über die Dreiecksmatrix wahrscheinlich sogar einfacher zu implementieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1854335</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1854335</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Thu, 11 Feb 2010 18:49:16 GMT</pubDate></item><item><title><![CDATA[Reply to Operator überladen für Zahlen und nicht speziell für double on Fri, 12 Feb 2010 07:58:43 GMT]]></title><description><![CDATA[<p>Sebastian Pizer schrieb:</p>
<blockquote>
<pre><code class="language-cpp">class Polynom
{
  std::vector&lt;double&gt; koeffs; // p(x) = Summe_i koeffs[i]*x^i
public:
  ...
  Polynom&amp; operator+=(Polynom const&amp; p);
  ...
};

Polynom&amp; Polynom::operator+=(Polynom const&amp; p)
{
  koeffs.resize( std::max(koeffs.size(),p.koeffs.size()) , 0.0 );
  for (int i=0, e=koeffs.size(); i&lt;e; ++i) {
    koeffs[i] += p.koeffs[i];
  }
  while (koeffs.size()&gt;0u &amp;&amp; koeffs.back()==0) {
    koeffs.pop_back();
  }
}
</code></pre>
</blockquote>
<p>Ich merke gerade, hier ist noch ein Bug drin. Falls p.koeffs.size() &lt; koeffs.size() greift die erste Schleife auf nicht vorhandene Elemente in p.koeffs zu. Es müsste <code>e=p.koeffs.size();</code> bei der for-Schleife heißen.</p>
<p>Andreas_L schrieb:</p>
<blockquote>
<p>Ja klar - aber die Sache ist doch das ich das freiwillig hobbymäßig selbst implementieren will um dabei auch besser zu lernen wie man mit so Problemen umgeht.</p>
</blockquote>
<p>Eigenwerte für Matrizen größer als 2x2 Elemente berechnen ist nichts, was man selbst programmieren können muss, echt nicht! Reine Zeitverschwendung. Das solltest Du als Baustein einfach benutzen können, mehr nicht. Wenn Du den Anspruch hast, die Algorithmen verstehen zu wollen, solltest Du dir das eine oder andere schlaue Numerik-Buch holen. Sei gewarnt.</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1854406</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1854406</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Fri, 12 Feb 2010 07:58:43 GMT</pubDate></item></channel></rss>