{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2022年度プログラミング演習A・B\n",
"\n",
"# 第13回レポート課題の解説"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 演習1(オプション)\n",
"\n",
"$n$ を自然数とし、関数\n",
"\n",
"$$\n",
"f(x)=\\sin\\left(2\\pi x^2\\right)\n",
"$$\n",
"\n",
"の節点\n",
"\n",
"$$\n",
"x_i=\\frac{i}{n}\\quad (i=0,\\ldots,n)\n",
"$$\n",
"\n",
"における補間多項式を考えます。\n",
"\n",
"$n=3,5,7$ の各場合に連立一次方程式を解くことによって補間多項式の係数を求め、$0\\leq x\\leq 1$ の範囲で元の関数 $f(x)$ と $3$ 個の補間多項式のグラフを描画してください。\n",
"\n",
"連立一次方程式を解く際には、演算子`\\`を使用してよいです。"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%plot --format svg\n",
"\n",
"function value = f(x) %f(x)を関数として定義しておく\n",
" value = sin(2*pi*x.^2);\n",
"end\n",
"\n",
"x = 0:0.01:1; %x座標の配列\n",
"y = f(x);\n",
"plot(x,y,\"DisplayName\",\"f(x)\") %f(x)のグラフを描画(凡例ラベルの設定付き)\n",
"grid on\n",
"hold on\n",
"\n",
"for n = [3,5,7] %for文でnを変化させる\n",
" node = (0:1/n:1)'; %節点の配列を縦ベクトルとして用意\n",
" A = zeros(n+1);\n",
" for j = 0:n\n",
" A(:,j+1) = node.^j; %行列Aの各列を計算\n",
" end\n",
" b = f(node); %縦ベクトルbを定める\n",
" c = A\\b; %連立一次方程式Ac=bを解いて係数ベクトルcを求める\n",
" y = 0;\n",
" for j = 0:n\n",
" y = y+c(j+1)*x.^j; %補間多項式を計算\n",
" end\n",
" plot(x,y,\"DisplayName\",[\"n=\",num2str(n)]) %補間多項式のグラフを描画(凡例ラベルの設定付き)\n",
"end\n",
"\n",
"legend %凡例の表示"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 演習2\n",
"\n",
"節点の配列`node`に対して`j`番目のラグランジュ基底多項式の`x`での値を返す関数`Lagrange(node,j,x)`を定義した上で、節点\n",
"\n",
"$$\n",
"x_0=0,\\quad x_1=\\frac{1}{4},\\quad x_2=\\frac{1}{2},\\quad x_3=\\frac{3}{4},\\quad x_4=1\n",
"$$\n",
"\n",
"に対する全てのラグランジュ基底多項式の $0\\leq x\\leq 1$ の範囲のグラフを描画してください。\n",
"\n",
"なお、関数の引数である`j`の範囲は、`0`~`length(node)-1`と`1`~`length(node)`のどちらで考えてもよいです。\n",
"\n",
"(どうしても難しければ、関数を定義せずにグラフの描画を行ってください。)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"関数の引数`j`の範囲を`0`~`length(node)-1`として考えることにすると、コードは次のようになる。"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%plot --format svg\n",
"\n",
"function value = Lagrange(node,j,x)\n",
" n = length(node)-1;\n",
" numerator = 1; %分子\n",
" denominator = 1; %分母\n",
" %二つのfor文を使ってk=jの場合を除いた計算を行う\n",
" %(一つのfor文で「k = [0:j-1,j+1:n]」とする、\n",
" % あるいは「k = 0:n」としてif文でk=jの場合にcontinueを使ってもよい)\n",
" for k = 0:j-1\n",
" numerator = numerator.*(x-node(k+1)); %定義に従って分子と分母に因数を掛ける 配列の成分ごとの掛け算は「.」が必要\n",
" denominator = denominator*(node(j+1)-node(k+1)); %数式の添え字と異なり、配列の成分番号は1から始まるために「+1」が必要\n",
" end\n",
" for k = j+1:n\n",
" numerator = numerator.*(x-node(k+1));\n",
" denominator = denominator*(node(j+1)-node(k+1));\n",
" end\n",
" value = numerator/denominator; %分子/分母を計算して値を返す\n",
"end\n",
"\n",
"x = 0:0.01:1; %x座標の配列\n",
"node = 0:1/4:1; %節点の配列\n",
"\n",
"for j = 0:length(node)-1\n",
" y = Lagrange(node,j,x); %定義した関数を呼び出して、ラグランジュ基底多項式の値を計算\n",
" plot(x,y) %ラグランジュ基底多項式のグラフを描画\n",
" grid on\n",
" hold on\n",
"end"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 演習3\n",
"\n",
"$n$ を自然数とし、関数\n",
"\n",
"$$\n",
"f(x)=\\sin\\left(2\\pi x^2\\right)\n",
"$$\n",
"\n",
"の節点\n",
"\n",
"$$\n",
"x_i=\\frac{i}{n}\\quad (i=0,\\ldots,n)\n",
"$$\n",
"\n",
"における補間多項式を考えます。\n",
"\n",
"$n=4,6$ の各場合にラグランジュ補間を用いて補間多項式を求め、$0\\leq x\\leq 1$ の範囲で元の関数 $f(x)$ と $2$ 個の補間多項式のグラフを描画してください。"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%plot --format svg\n",
"\n",
"function value = f(x) %f(x)を関数として定義しておく\n",
" value = sin(2*pi*x.^2);\n",
"end\n",
"\n",
"x = 0:0.01:1; %x座標の配列\n",
"y = f(x);\n",
"plot(x,y) %f(x)のグラフを描画\n",
"grid on\n",
"hold on\n",
"\n",
"for n = [4,6] %for文でnを変化させる\n",
" node = 0:1/n:1; %節点の配列\n",
" y = 0;\n",
" for j = 0:n\n",
" y = y+f(node(j+1))*Lagrange(node,j,x); %演習2の関数を利用して、ラグランジュ補間により補間多項式を計算\n",
" end\n",
" plot(x,y) %補間多項式のグラフを描画\n",
"end"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Octave",
"language": "octave",
"name": "octave"
},
"language_info": {
"file_extension": ".m",
"help_links": [
{
"text": "GNU Octave",
"url": "https://www.gnu.org/software/octave/support.html"
},
{
"text": "Octave Kernel",
"url": "https://github.com/Calysto/octave_kernel"
},
{
"text": "MetaKernel Magics",
"url": "https://metakernel.readthedocs.io/en/latest/source/README.html"
}
],
"mimetype": "text/x-octave",
"name": "octave",
"version": "5.2.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}