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

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

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

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

セグメンテーション違反

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

C++

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

Q&A

解決済

2回答

1928閲覧

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

Kinsho

総合スコア18

C

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

セグメンテーション違反

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

C++

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

0グッド

0クリップ

投稿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++

1#include <iostream> 2#include <string> 3#include <stdint.h> 4#include <vector> 5#include <stdio.h> 6#include <stdlib.h> 7#include <cmath> 8#include <iostream> 9#include <math.h> 10#include <fstream> 11#include <sstream> 12#include <algorithm> 13#include <chrono> 14#include <utility> 15#include <time.h> 16#include <tuple> 17#include <cstdint> 18#include <cstdio> 19//別のプログラムで使いたいのでincludeは極力このままで 20using namespace std; 21 22 23const int w = 400; 24using Mat = vector<vector<double>>; 25vector<double> parse_line(const string &line, char delim = ',') 26{ 27 vector<double> values; 28 29 istringstream ss(line); 30 string token; 31 while (getline(ss, token, delim)) 32 values.push_back(stod(token)); 33 return values; 34} 35Mat parse_csv(const string &path) 36{ 37 ifstream ifs(path); 38 string line; 39 Mat mat; 40 41 while (getline(ifs, line)) { 42 // 1行分解析する。 43 vector<double> values = parse_line(line); 44 mat.push_back(values); 45 } 46 return mat; 47} 48double sq[w][w]; 49double cb[w][w]; 50double a[w][w], b[w][w], c[w][w], d[w][w], e[w][w], f[w][w], g[w][w], h[w][w]; 51double s[w][w], t[w][w], k[w][w], l[w][w], m[w][w], n[w][w], o[w][w], p[w][w]; 52 53int main() { 54 55 56 Mat si; 57 try { 58 si = parse_csv("Bx.csv"); 59 } 60 catch (exception &e) { 61 cout << "Error: " << e.what() << "\n"; return 1; 62 } 63 64 int y=si.size(); // (縦の要素数)364 65 int x= si.at(0).size(); //(横の要素数)184 66 67 68 for(int i=0;i<y;i++) { 69 for (int j = 0; j<x; j++) { 70 sq[i][j] = si[i][j] * si[i][j]; 71 cb[i][j]= si[i][j] * si[i][j] * si[i][j]; 72 } 73 } 74 75 //ここまではうまくいっています. 76 77 78 //f=a*xxx+b*xxxy+c*xxxyy+d*xxxyyy 79 //+e*xx+f*xxy+g*xxyy+h*xxyyy 80 //+s*x+t*xy+k*xyy+l*xyyy 81 //+m+n*y+o*yy+p*yyy 82 83 //j-1,j,j+1,j+2 84 //i-1,1,2,3,4 85 //i,5,6,7,8 86 //i+1,9,10,11,12 87 //i+2,13,14,15,16 88 89 //多分ここからが問題と思われます 90 91 //1つずつ解く 92 for (int i = 2; i <= y - 3; i++) { 93 for (int j = 2; j <= x - 3; j++) { 94 //このループを各22~100などとしても同様のエラーが出るので 95 //問題はこのループの数字ではないと思います. 96 97 //連立方程式を解く 98 99 double z[16][17] = { 100 {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 101 { 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 102 { 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 103 { 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 104 { 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 105 { 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 106 { 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 107 { 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 108 { 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 109 { 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 110 { 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 111 { 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 112 { 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 113 { 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 114 { 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 115 { 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 116 }; 117 118 for (int ii = 0; ii<16; ii++) { 119 int maxLine = ii; 120 for (int jj = ii; jj<16; jj++) if (abs(z[maxLine][ii])<abs(z[jj][ii])) maxLine = jj; 121 for (int jj = ii; jj<= 16; jj++) swap(z[ii][jj], z[maxLine][jj]); 122 123 double beginNum = z[ii][ii]; 124 if (!beginNum) { 125 cout << "can not calc" << endl; 126 return 0; 127 } 128 129 for (int jj = ii; jj <= 16; jj++)z[ii][jj] /= beginNum; 130 131 for (int jj = ii + 1; jj<16; jj++) { 132 double beginDelete = z[jj][ii]; 133 for (int k = ii; k <= 16; k++)z[jj][k] -= beginDelete*z[ii][k]; 134 } 135 } 136 for (int ii = 15; ii >= 0; ii--) { 137 for (int jj = ii + 1; jj<16; jj++)z[ii][16] -= z[jj][16] * z[ii][jj]; 138 } 139 a[i][j] = z[0][16]; 140 b[i][j] = z[1][16]; 141 c[i][j] = z[2][16]; 142 d[i][j] = z[3][16]; 143 e[i][j] = z[4][16]; 144 f[i][j] = z[5][16]; 145 g[i][j] = z[6][16]; 146 h[i][j] = z[7][16]; 147 s[i][j] = z[8][16]; 148 t[i][j] = z[9][16]; 149 k[i][j] = z[10][16]; 150 l[i][j] = z[11][16]; 151 m[i][j] = z[12][16]; 152 n[i][j] = z[13][16]; 153 o[i][j] = z[14][16]; 154 p[i][j] = z[15][16]; 155 156 } 157 } 158 159 160 cout << o[244][55];//無事に解析できたかとりあえず確認 161 162 163 164 //この問題が解決後自分でここに続きを打ち込む予定です 165 166 return 0; 167} 168 169 170 171

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

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

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

回答2

0

自己解決

皆様のご指摘の個所を修正後連立方程式の不定解問題の解消(厳密には近似)方法について自己解決ができましたのでのちに同じ問題に直面する方のために共有しておきます.

csvのxy座標に同じものが入っているとrank16を確保できないので,x=0,0.01,0.02,...のように始まる場合は最初の列をコピペした後にx=「-0.00000001」,0,0.01,0.02,...のようにするとrank16を確保できて16本の連立方程式で解が求まる.またこのデータの縦列のように中間に0をまたぐ場合はその0を同様に0.00000001などとしてやるといいと思います.

投稿2020/09/07 14:30

Kinsho

総合スコア18

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

iやjを使ったforループの中に,iやjを使ったforが記述されているので,
その動作は想定通りではないものと推測されます.

投稿2020/09/07 10:26

fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kinsho

2020/09/07 10:48

確かにそこはうっかりしていました.ご指摘ありがとうございます. ただi,jループ内にあったi,jをとりあえずii,jjなどとしてみましたが同様のエラーを返されてしまいました...
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問