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
回答2件
あなたの回答
tips
プレビュー