質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

セグメンテーション違反

セグメンテーション違反とは、ソフトウェア実行時に発生するエラーのひとつであり、許可されていないメモリにアクセスしたときに起きます。しばしば、ポインタの不適切な使用、またはバッファオーバーフローによって起こります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

解決済

C++で2次元の3次スプライン補間.方程式の解が不定の場合の対処法について

Kinsho
Kinsho

総合スコア17

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

セグメンテーション違反

セグメンテーション違反とは、ソフトウェア実行時に発生するエラーのひとつであり、許可されていないメモリにアクセスしたときに起きます。しばしば、ポインタの不適切な使用、またはバッファオーバーフローによって起こります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

2回答

0リアクション

0クリップ

958閲覧

投稿2020/09/07 10:15

編集2020/09/07 11:57

C++で2次元の3次スプライン補間を行おうと考えています.
元々のcsvはこのBx.csv( https://drive.google.com/file/d/1vcpLAAZIc6EL4QZ8YTfYthSwZu7UqGWR/view?usp=sharing )というファイルを使用します.
このファイルの1行目がx座標,1列目がy座標を表しています.
それを2乗3乗した2次元配列を作成しそれを基に16本の連立方程式を作り,それを解くことによって0.01×0.01の各マス内における3次スプライン補間式の係数を導出したいです.
添付プログラム序盤のcsvの読み取りはこちら( https://teratail.com/questions/289856 )を,連立方程式の解き方はこちら( https://qiita.com/kubo_programmer/items/c42ec88bdba3c5c0919f )を参考にさせていただきました.

これで計算したところcan not calc(自分で作成したエラー文です)と返されてしまいます.
おそらくcsvの中に値が十分に散らばっていない部分があり連立方程式の解が一位に定まらずエラーになってしまうのだと考えられます.
当然すべてのセルにとりあえず1を足すなどの処理は無意味で根本的な対策が必要みたいです.

このような場合に良い対処法などはありますでしょうか?

結果(2次元配列a~p)はこの後に別のプログラムで使いたいと思っていて,この計算がうまくいったらそれを別のcsvにでも格納して使いたいと思ってるので,最後の部分はこのままでいきたいです.

1日考えましたが現在の私の力ではどうにも解決できなさそうなので解決法をご教示いただけますと幸いです.
よろしくお願いします.

該当のソースコード

c++

#include <iostream> #include <string> #include <stdint.h> #include <vector> #include <stdio.h> #include <stdlib.h> #include <cmath> #include <iostream> #include <math.h> #include <fstream> #include <sstream> #include <algorithm> #include <chrono> #include <utility> #include <time.h> #include <tuple> #include <cstdint> #include <cstdio> //別のプログラムで使いたいのでincludeは極力このままで using namespace std; const int w = 400; using Mat = vector<vector<double>>; vector<double> parse_line(const string &line, char delim = ',') { vector<double> values; istringstream ss(line); string token; while (getline(ss, token, delim)) values.push_back(stod(token)); return values; } Mat parse_csv(const string &path) { ifstream ifs(path); string line; Mat mat; while (getline(ifs, line)) { // 1行分解析する。 vector<double> values = parse_line(line); mat.push_back(values); } return mat; } double sq[w][w]; double cb[w][w]; double a[w][w], b[w][w], c[w][w], d[w][w], e[w][w], f[w][w], g[w][w], h[w][w]; double s[w][w], t[w][w], k[w][w], l[w][w], m[w][w], n[w][w], o[w][w], p[w][w]; int main() { Mat si; try { si = parse_csv("Bx.csv"); } catch (exception &e) { cout << "Error: " << e.what() << "\n"; return 1; } int y=si.size(); // (縦の要素数)364 int x= si.at(0).size(); //(横の要素数)184 for(int i=0;i<y;i++) { for (int j = 0; j<x; j++) { sq[i][j] = si[i][j] * si[i][j]; cb[i][j]= si[i][j] * si[i][j] * si[i][j]; } } //ここまではうまくいっています. //f=a*xxx+b*xxxy+c*xxxyy+d*xxxyyy //+e*xx+f*xxy+g*xxyy+h*xxyyy //+s*x+t*xy+k*xyy+l*xyyy //+m+n*y+o*yy+p*yyy //j-1,j,j+1,j+2 //i-1,1,2,3,4 //i,5,6,7,8 //i+1,9,10,11,12 //i+2,13,14,15,16 //多分ここからが問題と思われます //1つずつ解く for (int i = 2; i <= y - 3; i++) { for (int j = 2; j <= x - 3; j++) { //このループを各22~100などとしても同様のエラーが出るので //問題はこのループの数字ではないと思います. //連立方程式を解く double z[16][17] = { {cb[0][j - 1],cb[0][j - 1] * si[i - 1][0],cb[0][j - 1] * sq[i - 1][0],cb[0][j - 1] * cb[i - 1][0],sq[0][j - 1], sq[0][j - 1] * si[i - 1][0], sq[0][j - 1] * sq[i - 1][0], sq[0][j - 1] * cb[i - 1][0], si[0][j - 1], si[0][j - 1] * si[i - 1][0], si[0][j - 1] * sq[i - 1][0], si[0][j - 1] * cb[i - 1][0], 1, si[i - 1][0], sq[i - 1][0], cb[i - 1][0],si[i-1][j-1]},//1 { cb[0][j],cb[0][j ] * si[i - 1][0],cb[0][j ] * sq[i - 1][0],cb[0][j ] * cb[i - 1][0],sq[0][j], sq[0][j ] * si[i - 1][0], sq[0][j ] * sq[i - 1][0], sq[0][j ] * cb[i - 1][0],si[0][j], si[0][j] * si[i - 1][0], si[0][j ] * sq[i - 1][0], si[0][j ] * cb[i - 1][0],1, si[i - 1][0], sq[i - 1][0], cb[i - 1][0], si[i - 1][j ] },//2 { cb[0][j + 1],cb[0][j + 1] * si[i - 1][0],cb[0][j + 1] * sq[i - 1][0],cb[0][j + 1] * cb[i - 1][0],sq[0][j + 1], sq[0][j + 1] * si[i - 1][0], sq[0][j + 1] * sq[i - 1][0], sq[0][j + 1] * cb[i - 1][0],si[0][j + 1], si[0][j + 1] * si[i - 1][0], si[0][j + 1] * sq[i - 1][0], si[0][j + 1] * cb[i - 1][0],1,si[i - 1][0], sq[i - 1][0], cb[i - 1][0] , si[i - 1][j + 1] },//3 { cb[0][j + 2],cb[0][j + 2] * si[i - 1][0],cb[0][j + 2] * sq[i - 1][0],cb[0][j + 2] * cb[i - 1][0],sq[0][j + 2], sq[0][j + 2] * si[i - 1][0], sq[0][j + 2] * sq[i - 1][0], sq[0][j + 2] * cb[i - 1][0],si[0][j + 2], si[0][j + 2] * si[i - 1][0], si[0][j + 2] * sq[i - 1][0], si[0][j + 2] * cb[i - 1][0],1, si[i - 1][0], sq[i - 1][0], cb[i - 1][0], si[i - 1][j +2] },//4 { cb[0][j - 1],cb[0][j - 1] * si[i ][0],cb[0][j - 1] * sq[i ][0],cb[0][j - 1] * cb[i ][0],sq[0][j - 1], sq[0][j - 1] * si[i ][0], sq[0][j - 1] * sq[i ][0], sq[0][j - 1] * cb[i ][0],si[0][j - 1], si[0][j - 1] * si[i ][0], si[0][j - 1] * sq[i ][0], si[0][j - 1] * cb[i ][0],1, si[i ][0], sq[i ][0], cb[i ][0],si[i ][j - 1] },//5 { cb[0][j ],cb[0][j ] * si[i][0],cb[0][j ] * sq[i][0],cb[0][j ] * cb[i][0], sq[0][j ], sq[0][j ] * si[i][0], sq[0][j] * sq[i][0], sq[0][j ] * cb[i][0],si[0][j ], si[0][j ] * si[i][0], si[0][j] * sq[i][0], si[0][j ] * cb[i][0],1,si[i][0], sq[i][0], cb[i][0],si[i][j] },//6 { cb[0][j + 1],cb[0][j + 1] * si[i][0],cb[0][j + 1] * sq[i][0],cb[0][j + 1] * cb[i][0],sq[0][j +1], sq[0][j + 1] * si[i][0], sq[0][j +1] * sq[i][0], sq[0][j + 1] * cb[i][0],si[0][j + 1], si[0][j + 1] * si[i][0], si[0][j + 1] * sq[i][0], si[0][j + 1] * cb[i][0],1,si[i][0], sq[i][0], cb[i][0],si[i][j + 1] },//7 { cb[0][j + 2],cb[0][j + 2] * si[i][0],cb[0][j + 2] * sq[i][0],cb[0][j + 2] * cb[i][0],sq[0][j + 2], sq[0][j + 2] * si[i][0], sq[0][j + 2] * sq[i][0], sq[0][j + 2] * cb[i][0],si[0][j + 2], si[0][j + 2] * si[i][0], si[0][j + 2] * sq[i][0], si[0][j + 2] * cb[i][0], 1, si[i][0], sq[i][0], cb[i][0],si[i][j + 2] },//8 { cb[0][j - 1],cb[0][j - 1] * si[i + 1][0],cb[0][j - 1] * sq[i + 1][0],cb[0][j - 1] * cb[i + 1][0],sq[0][j - 1], sq[0][j - 1] * si[i + 1][0], sq[0][j - 1] * sq[i + 1][0], sq[0][j - 1] * cb[i + 1][0],si[0][j - 1], si[0][j - 1] * si[i + 1][0], si[0][j - 1] * sq[i + 1][0], si[0][j - 1] * cb[i + 1][0],1, si[i - 1][0], sq[i + 1][0], cb[i + 1][0],si[i + 1][j - 1] },//9 { cb[0][j],cb[0][j] * si[i + 1][0],cb[0][j] * sq[i + 1][0],cb[0][j] * cb[i + 1][0],sq[0][j], sq[0][j] * si[i + 1][0], sq[0][j] * sq[i + 1][0], sq[0][j] * cb[i + 1][0],si[0][j], si[0][j] * si[i + 1][0], si[0][j] * sq[i + 1][0], si[0][j] * cb[i + 1][0],1, si[i + 1][0], sq[i + 1][0], cb[i + 1][0], si[i +1][j] },//10 { cb[0][j + 1],cb[0][j + 1] * si[i + 1][0],cb[0][j + 1] * sq[i + 1][0],cb[0][j + 1] * cb[i + 1][0],sq[0][j + 1], sq[0][j + 1] * si[i + 1][0], sq[0][j + 1] * sq[i + 1][0], sq[0][j + 1] * cb[i + 1][0],si[0][j + 1], si[0][j + 1] * si[i + 1][0], si[0][j + 1] * sq[i + 1][0], si[0][j + 1] * cb[i + 1][0],1,si[i + 1][0], sq[i + 1][0], cb[i + 1][0] , si[i + 1][j + 1] },//11 { cb[0][j + 2],cb[0][j + 2] * si[i + 1][0],cb[0][j + 2] * sq[i + 1][0],cb[0][j + 2] * cb[i + 1][0],sq[0][j + 2], sq[0][j + 2] * si[i + 1][0], sq[0][j + 2] * sq[i + 1][0], sq[0][j + 2] * cb[i + 1][0],si[0][j + 2], si[0][j + 2] * si[i + 1][0], si[0][j + 2] * sq[i + 1][0], si[0][j + 2] * cb[i + 1][0],1,si[i + 1][0], sq[i+1][0], cb[i + 1][0],si[i + 1][j + 2] },//12 { cb[0][j - 1],cb[0][j - 1] * si[i + 2][0],cb[0][j - 1] * sq[i + 2][0],cb[0][j - 1] * cb[i + 2][0],sq[0][j - 1], sq[0][j - 1] * si[i + 2][0], sq[0][j - 1] * sq[i + 2][0], sq[0][j - 1] * cb[i + 2][0],si[0][j - 1], si[0][j - 1] * si[i + 2][0], si[0][j - 1] * sq[i + 2][0], si[0][j - 1] * cb[i + 2][0],1, si[i +2][0], sq[i + 2][0], cb[i + 2][0],si[i + 2][j - 1] },//13 { cb[0][j],cb[0][j] * si[i + 2][0],cb[0][j] * sq[i + 2][0],cb[0][j] * cb[i + 2][0],sq[0][j], sq[0][j] * si[i + 2][0], sq[0][j] * sq[i + 2][0], sq[0][j] * cb[i + 2][0], si[0][j], si[0][j] * si[i + 2][0], si[0][j] * sq[i + 2][0], si[0][j] * cb[i + 2][0], 1, si[i + 2][0], sq[i + 2][0], cb[i + 2][0], si[i + 2][j] },//14 { cb[0][j + 1],cb[0][j + 1] * si[i + 2][0],cb[0][j + 1] * sq[i + 2][0],cb[0][j + 1] * cb[i + 2][0],sq[0][j + 1], sq[0][j + 1] * si[i + 2][0], sq[0][j + 1] * sq[i + 2][0], sq[0][j + 1] * cb[i + 2][0],si[0][j + 1], si[0][j + 1] * si[i + 2][0], si[0][j + 1] * sq[i + 2][0], si[0][j + 1] * cb[i + 2][0],1, si[i + 2][0], sq[i + 2][0], cb[i + 2][0] , si[i + 2][j + 1] },//15 { cb[0][j + 2],cb[0][j + 2] * si[i + 2][0],cb[0][j + 2] * sq[i + 2][0],cb[0][j + 2] * cb[i + 2][0],sq[0][j + 2], sq[0][j + 2] * si[i + 2][0], sq[0][j + 2] * sq[i + 2][0], sq[0][j + 2] * cb[i + 2][0],si[0][j + 2], si[0][j + 2] * si[i + 2][0], si[0][j + 2] * sq[i + 2][0], si[0][j + 2] * cb[i + 2][0], 1, si[i + 2][0], sq[i + 2][0], cb[i + 2][0],si[i + 2][j + 2] }//16 }; for (int ii = 0; ii<16; ii++) { int maxLine = ii; for (int jj = ii; jj<16; jj++) if (abs(z[maxLine][ii])<abs(z[jj][ii])) maxLine = jj; for (int jj = ii; jj<= 16; jj++) swap(z[ii][jj], z[maxLine][jj]); double beginNum = z[ii][ii]; if (!beginNum) { cout << "can not calc" << endl; return 0; } for (int jj = ii; jj <= 16; jj++)z[ii][jj] /= beginNum; for (int jj = ii + 1; jj<16; jj++) { double beginDelete = z[jj][ii]; for (int k = ii; k <= 16; k++)z[jj][k] -= beginDelete*z[ii][k]; } } for (int ii = 15; ii >= 0; ii--) { for (int jj = ii + 1; jj<16; jj++)z[ii][16] -= z[jj][16] * z[ii][jj]; } a[i][j] = z[0][16]; b[i][j] = z[1][16]; c[i][j] = z[2][16]; d[i][j] = z[3][16]; e[i][j] = z[4][16]; f[i][j] = z[5][16]; g[i][j] = z[6][16]; h[i][j] = z[7][16]; s[i][j] = z[8][16]; t[i][j] = z[9][16]; k[i][j] = z[10][16]; l[i][j] = z[11][16]; m[i][j] = z[12][16]; n[i][j] = z[13][16]; o[i][j] = z[14][16]; p[i][j] = z[15][16]; } } cout << o[244][55];//無事に解析できたかとりあえず確認 //この問題が解決後自分でここに続きを打ち込む予定です return 0; }

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

cateye

2020/09/07 10:36

double a[w][w], b[w][w], c[w][w], d[w][w], e[w][w], f[w][w], g[w][w], h[w][w]; double s[w][w], t[w][w], k[w][w], l[w][w], m[w][w], n[w][w], o[w][w], p[w][w]; ・・・で、何MBになりますか?・・・スタックにこれだけ取れるのでしょうか?
Kinsho

2020/09/07 10:53

ご回答ありがとうございます.家庭用ゲーミングPCで弾かれるのは当然予想していましたが数値計算を専門にしている研究室の計算機でもエラーを返されてしまいました. これくらいの容量ならスタックは問題なく置けるスペックだと思われます.
mjk

2020/09/07 11:05

(研究室の計算機のスタックが特殊なのかは分かりませんが) cateyeさんがご指摘されていますが、 double sq[w][w]; double cb[w][w]; その他配列をグローバル宣言にしてみるなどを試してみましたか? 私も似たような経験がありもしかしたらそれで解決するかもしれません。 https://teratail.com/questions/285169 配列サイズが大きくなりすぎるとメモリ不足になるのでそちらが原因では無いかとのご指摘かと思います。 それでも同様のエラーが出るようなら範囲外の配列を参照しているなどが疑われます。 配列[10]しかないのに配列[11]を参照しようとしたなど。
Kinsho

2020/09/07 11:28

ご指摘ありがとうございます.ご指摘の通り配列宣言を全てグローバル変数の外に出したらその問題は解決できました.素人ゆえにPCのスペックを盲信していた私が間違っていました.
mjk

2020/09/07 11:31

いえいえ初心者の私も直感で動くはずなのに何故動かないのか分からずに戸惑いました。 質問して回答してくださった方に教えて頂き初めて理解しました。 回答してくださった方に感謝しております。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

セグメンテーション違反

セグメンテーション違反とは、ソフトウェア実行時に発生するエラーのひとつであり、許可されていないメモリにアクセスしたときに起きます。しばしば、ポインタの不適切な使用、またはバッファオーバーフローによって起こります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。