これは宿題のように思われるので、私はあなたに徹底的な答えを与えるつもりはありませんが、むしろあなたを正しい軌道に乗せるように努めます。
- コンピュータソフトウェアで多項式をどのように表現しますか?3x ^ 3 + 5x ^ 24-のようなシンボリック式としてアーカイブしたい直感的なバージョンは、それ以上の計算には非常に実用的ではありません。
- 多項式は、その係数を保存(および出力)することによって完全に定義されます。
上記で行っていることは、C ++が代数的な操作を行い、シンボリック変数を使用して製品を単純化することを望んでいます。これは、C++がかなりの労力なしで実行できることではありません。
2つのオプションがあります。
- 記号操作を実行できる適切な数式処理システムを使用してください(MapleまたはMathematicaがいくつかの例です)
- C ++に縛られている場合は、多項式の単一係数を計算する方法をもう少し考える必要があります。プログラムの出力は、数値のリストのみにすることができます(もちろん、記号式に従って見栄えの良い文字列としてフォーマットすることもできます)。
これがあなたに始める方法のいくつかのアイデアを与えることを願っています。
編集1
に値を設定することはないため、コードにはまだ未定義の式がありますy
。これはprod*=(y-x[i])/(x[k]-x[i])
、意味のあるデータを返さない式として残ります。C ++は数字でしか機能せず、現時点では数字でy
はありませんが、記号と考えてください。
コードで設定する場合は、たとえば値でラグレンジ近似を評価できます。これにより、(私が今見る限り)正しい関数値が得られますが、関数自体の説明はありません。1
y=1
たぶん、最初にペンと一枚の紙を取り、その表現を正確な数学として書き留めてみるべきでしょう。計算したいものを実際に把握してみてください。もしそうなら、多分あなたはここに戻ってあなたの考えを教えてください。これは、そこで何が起こっているのかを理解するのに役立つはずです。
そして、常に覚えておいてください。C++には、記号ではなく数字が必要です。紙の表現に値がわからない記号がある場合は、既知の値から値を計算する方法を見つけるか、この記号を使用して計算する必要をなくす必要があります。
PS:一度に複数の掲示板に同じ質問を投稿するのは良いスタイルとは見なされません...
編集2
ここで、点y=0.3で関数を評価します。これは、多項式を評価する場合の方法です。ただし、あなたが述べたように、あなたは多項式のすべての係数が必要です。
繰り返しますが、私はまだあなたが問題の背後にある数学を理解していなかったと感じています。たぶん私はあなたに小さな例をあげます。ウィキペディアの記事で使用されている表記を使用します。
k=2およびx=-1、1であると仮定します。さらに、簡単にするために、cos-Functionfという名前を付けます。(ラテックスがないと表記はかなり醜くなります...)次に、ラグランジュ多項式は次のように定義されます。
f(x_0) * l_0(x) + f(x_1)*l_1(x)
ここで(単純化を再び象徴的に行うことによって)
l_0(x)= (x - x_1)/(x_0 - x_1) = -1/2 * (x-1) = -1/2 *x + 1/2
l_1(x)= (x - x_0)/(x_1 - x_0) = 1/2 * (x+1) = 1/2 * x + 1/2
つまり、ラグランジュ多項式は
f(x_0) * (-1/2 *x + 1/2) + f(x_1) * 1/2 * x + 1/2
= 1/2 * (f(x_1) - f(x_0)) * x + 1/2 * (f(x_0) + f(x_1))
したがって、計算する係数は1/2 *(f(x_1)-f(x_0))および1/2 *(f(x_0)+ f(x_1))になります。
あなたの仕事は、私が行った単純化を実行するアルゴリズムを見つけることですが、シンボルは使用しません。l_jの係数を計算する方法を知っていれば、基本的には完了です。これで、対応するfの値を掛けたものを合計することができます。
したがって、さらに細かく分類すると、l_jの商をコンポーネントごとに相互に乗算する方法を見つける必要があります。これがどのように行われるかを理解すれば、ほぼ完了です。
編集3
さて、もう少し曖昧さを減らしましょう。
まず、L_i(x)を計算します。これらは線形関数の単なる積です。前に述べたように、各多項式を係数の配列として表す必要があります。良いスタイルのためstd::vector
に、この配列の代わりに使用します。次に、L_1(x)の係数を保持するデータ構造を次のように定義できます。
std::vector L1 = std::vector(5);
// Lets assume our polynomial would then have the form
// L1[0] + L2[1]*x^1 + L2[2]*x^2 + L2[3]*x^3 + L2[4]*x^4
ここで、この多項式を値で埋めたいと思います。
// First we have start with the polynomial 1 (which is of degree 0)
// Therefore set L1 accordingly:
L1[0] = 1;
L1[1] = 0; L1[2] = 0; L1[3] = 0; L1[4] = 0;
// Of course you could do this more elegant (using std::vectors constructor, for example)
for (int i = 0; i < N+1; ++i) {
if (i==0) continue; /// For i=0, there will be no polynomial multiplication
// Otherwise, we have to multiply L1 with the polynomial
// (x - x[i]) / (x[0] - x[i])
// First, note that (x[0] - x[i]) ist just a scalar; we will save it:
double c = (x[0] - x[i]);
// Now we multiply L_1 first with (x-x[1]). How does this multiplication change our
// coefficients? Easy enough: The coefficient of x^1 for example is just
// L1[0] - L1[1] * x[1]. Other coefficients are done similary. Futhermore, we have
// to divide by c, which leaves our coefficient as
// (L1[0] - L1[1] * x[1])/c. Let's apply this to the vector:
L1[4] = (L1[3] - L1[4] * x[1])/c;
L1[3] = (L1[2] - L1[3] * x[1])/c;
L1[2] = (L1[1] - L1[2] * x[1])/c;
L1[1] = (L1[0] - L1[1] * x[1])/c;
L1[0] = ( - L1[0] * x[1])/c;
// There we are, polynomial updated.
}
もちろん、これはすべてのL_iに対して実行する必要があります。その後、L_iを追加し、関数を乗算する必要があります。それはあなたが理解するためのものです。(私はそこにかなり多くの非効率的なものを作ったことに注意してください、しかしこれがあなたが詳細をよりよく理解するのに役立つことを願っています。)
うまくいけば、これはあなたがどのように進むことができるかについてあなたにいくつかの考えを与えるでしょう。