This lib is considered to be used as a sensor's calibration program. Calibration with Spline Interpolation might be useful in the case that you want some model expressing relationship such like between a value of physical quantity and your sensor's voltage, but you cannot estimate a model such as liner, square, cubic polynomial, or sine curve. This makes (Parametric) Cubic Spline Polynomial Model (Coefficients of the polynomial) from some sample plots(e.g. sets of (value, voltage)). The inverse function (x,y)->(y,x) has been implemented so as to get analog data (not stepping or leveled data).

Fork of TRP105F_Spline by Akifumi Takahashi

Committer:
aktk
Date:
Sun May 29 09:31:44 2016 +0000
Revision:
11:a279e31d8499
Parent:
10:607a68db6303
Child:
12:b3e07a2220bc
In _solve_cubic_f, pow(u,1/3) -> exp(log(u)/3)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
aktk 9:1903c6f8d5a9 1 #define DEBUG
aktk 9:1903c6f8d5a9 2 #include "CubicSpline.h"
aktk 9:1903c6f8d5a9 3
aktk 9:1903c6f8d5a9 4 // To get voltage of TRP105F
aktk 9:1903c6f8d5a9 5 AnalogIn g_Sensor_Voltage(p16);
aktk 9:1903c6f8d5a9 6 // To get sample distance via seral com
aktk 9:1903c6f8d5a9 7 Serial g_Serial_Signal(USBTX, USBRX);
aktk 9:1903c6f8d5a9 8
aktk 9:1903c6f8d5a9 9 LocalFileSystem local("local"); // マウントポイントを定義(ディレクトリパスになる)
aktk 9:1903c6f8d5a9 10 // for debug
aktk 9:1903c6f8d5a9 11 #ifdef DEBUG
aktk 9:1903c6f8d5a9 12 DigitalOut led1(LED1);
aktk 9:1903c6f8d5a9 13 DigitalOut led2(LED2);
aktk 9:1903c6f8d5a9 14 DigitalOut led3(LED3);
aktk 9:1903c6f8d5a9 15 DigitalOut led4(LED4);
aktk 9:1903c6f8d5a9 16 #endif
aktk 9:1903c6f8d5a9 17
aktk 9:1903c6f8d5a9 18 CubicSpline2d::CubicSpline2d()
aktk 9:1903c6f8d5a9 19 :_useType(AsMODULE)
aktk 9:1903c6f8d5a9 20 {
aktk 9:1903c6f8d5a9 21 _Sample_Num = 5;
aktk 9:1903c6f8d5a9 22 _Sample_Set = (Vxyt *)malloc(_Sample_Num * sizeof(Vxyt));
aktk 9:1903c6f8d5a9 23 _Last_Point = (Vxyt) {
aktk 9:1903c6f8d5a9 24 0,0,0
aktk 9:1903c6f8d5a9 25 };
aktk 9:1903c6f8d5a9 26 for(int i = 0; i < 4; i++) {
aktk 9:1903c6f8d5a9 27 _C_x[i]= (double*)malloc((_Sample_Num - 1)* sizeof(double));;
aktk 9:1903c6f8d5a9 28 _C_y[i]= (double*)malloc((_Sample_Num - 1)* sizeof(double));;
aktk 9:1903c6f8d5a9 29 }
aktk 9:1903c6f8d5a9 30 //calibrateSensor();
aktk 9:1903c6f8d5a9 31 }
aktk 9:1903c6f8d5a9 32
aktk 9:1903c6f8d5a9 33 CubicSpline2d::CubicSpline2d(
aktk 9:1903c6f8d5a9 34 unsigned int arg_num
aktk 9:1903c6f8d5a9 35 )
aktk 9:1903c6f8d5a9 36 :_useType(AsMODULE)
aktk 9:1903c6f8d5a9 37 {
aktk 9:1903c6f8d5a9 38 _Sample_Num = arg_num;
aktk 9:1903c6f8d5a9 39 _Sample_Set = (Vxyt *)malloc(_Sample_Num * sizeof(Vxyt));
aktk 9:1903c6f8d5a9 40 _Last_Point = (Vxyt) {
aktk 9:1903c6f8d5a9 41 0,0,0
aktk 9:1903c6f8d5a9 42 };
aktk 9:1903c6f8d5a9 43 for(int i = 0; i < 4; i++) {
aktk 9:1903c6f8d5a9 44 _C_x[i]= (double*)malloc((_Sample_Num - 1)* sizeof(double));;
aktk 9:1903c6f8d5a9 45 _C_y[i]= (double*)malloc((_Sample_Num - 1)* sizeof(double));;
aktk 9:1903c6f8d5a9 46 }
aktk 9:1903c6f8d5a9 47 //calibrateSensor();
aktk 9:1903c6f8d5a9 48 }
aktk 9:1903c6f8d5a9 49
aktk 9:1903c6f8d5a9 50 CubicSpline2d::CubicSpline2d(
aktk 9:1903c6f8d5a9 51 unsigned int arg_num,
aktk 9:1903c6f8d5a9 52 UseType arg_useType
aktk 9:1903c6f8d5a9 53 )
aktk 9:1903c6f8d5a9 54 :_useType(arg_useType)
aktk 9:1903c6f8d5a9 55 {
aktk 9:1903c6f8d5a9 56 _Sample_Num = arg_num;
aktk 9:1903c6f8d5a9 57 _Sample_Set = (Vxyt *)malloc(_Sample_Num * sizeof(Vxyt));
aktk 9:1903c6f8d5a9 58 _Last_Point = (Vxyt) {
aktk 9:1903c6f8d5a9 59 0,0,0
aktk 9:1903c6f8d5a9 60 };
aktk 9:1903c6f8d5a9 61 for(int i = 0; i < 4; i++) {
aktk 9:1903c6f8d5a9 62 _C_x[i]= (double*)malloc((_Sample_Num - 1)* sizeof(double));;
aktk 9:1903c6f8d5a9 63 _C_y[i]= (double*)malloc((_Sample_Num - 1)* sizeof(double));;
aktk 9:1903c6f8d5a9 64 }
aktk 9:1903c6f8d5a9 65 //calibrateSensor();
aktk 9:1903c6f8d5a9 66 }
aktk 9:1903c6f8d5a9 67
aktk 9:1903c6f8d5a9 68 CubicSpline2d::~CubicSpline2d()
aktk 9:1903c6f8d5a9 69 {
aktk 9:1903c6f8d5a9 70 free(_Sample_Set);
aktk 9:1903c6f8d5a9 71 //free(_u_param);
aktk 9:1903c6f8d5a9 72 for(int i = 0; i < 4; i++) {
aktk 9:1903c6f8d5a9 73 free(_C_x[i]);
aktk 9:1903c6f8d5a9 74 free(_C_y[i]);
aktk 9:1903c6f8d5a9 75 }
aktk 9:1903c6f8d5a9 76 }
aktk 9:1903c6f8d5a9 77
aktk 9:1903c6f8d5a9 78 void CubicSpline2d::_sampleData()
aktk 9:1903c6f8d5a9 79 {
aktk 9:1903c6f8d5a9 80 int tmp;
aktk 9:1903c6f8d5a9 81 char sig;
aktk 9:1903c6f8d5a9 82 Vxyt tmp_set;
aktk 9:1903c6f8d5a9 83
aktk 9:1903c6f8d5a9 84 int floatflag = 0;
aktk 9:1903c6f8d5a9 85
aktk 9:1903c6f8d5a9 86 // For evry set,
aktk 9:1903c6f8d5a9 87 // 1, get dst data via serai com,
aktk 9:1903c6f8d5a9 88 // 2, get vol data,
aktk 9:1903c6f8d5a9 89 // and then do same for next index set.
aktk 9:1903c6f8d5a9 90 for(int i = 0; i < _Sample_Num; i++) {
aktk 9:1903c6f8d5a9 91 if(_useType == AsDEBUG) {
aktk 9:1903c6f8d5a9 92 //
aktk 9:1903c6f8d5a9 93 // Recieve a Distance datus and store it into member
aktk 9:1903c6f8d5a9 94 //
aktk 9:1903c6f8d5a9 95 g_Serial_Signal.printf("X:");
aktk 9:1903c6f8d5a9 96 _Sample_Set[i].x = 0;
aktk 9:1903c6f8d5a9 97 do {
aktk 9:1903c6f8d5a9 98 sig = g_Serial_Signal.getc();
aktk 9:1903c6f8d5a9 99 if('0' <= sig && sig <= '9') {
aktk 9:1903c6f8d5a9 100 if(floatflag == 0) {
aktk 9:1903c6f8d5a9 101 _Sample_Set[i].x = 10 * _Sample_Set[i].x + sig - 48;
aktk 9:1903c6f8d5a9 102 } else {
aktk 9:1903c6f8d5a9 103 _Sample_Set[i].x = _Sample_Set[i].x + (sig - 48) * pow((double)10, (double)- floatflag);
aktk 9:1903c6f8d5a9 104 floatflag++;
aktk 9:1903c6f8d5a9 105 }
aktk 9:1903c6f8d5a9 106 g_Serial_Signal.putc(char(sig));
aktk 9:1903c6f8d5a9 107 } else if(sig == '.') {
aktk 9:1903c6f8d5a9 108 if(floatflag == 0) {
aktk 9:1903c6f8d5a9 109 floatflag = 1;
aktk 9:1903c6f8d5a9 110 g_Serial_Signal.putc(char(sig));
aktk 9:1903c6f8d5a9 111 }
aktk 9:1903c6f8d5a9 112 } else if(sig == 0x08) {
aktk 9:1903c6f8d5a9 113 _Sample_Set[i].x = 0;
aktk 9:1903c6f8d5a9 114 g_Serial_Signal.printf("[canseled!]");
aktk 9:1903c6f8d5a9 115 g_Serial_Signal.putc('\n');
aktk 9:1903c6f8d5a9 116 g_Serial_Signal.putc('>');
aktk 9:1903c6f8d5a9 117 }
aktk 9:1903c6f8d5a9 118 } while (!(sig == 0x0a || sig == 0x0d));
aktk 9:1903c6f8d5a9 119 floatflag = 0;
aktk 9:1903c6f8d5a9 120 g_Serial_Signal.putc('\n');
aktk 9:1903c6f8d5a9 121 g_Serial_Signal.printf("x:%f|",_Sample_Set[i].x);
aktk 9:1903c6f8d5a9 122 //
aktk 9:1903c6f8d5a9 123 // Recieve a Voltage datus and store it into member
aktk 9:1903c6f8d5a9 124 //
aktk 9:1903c6f8d5a9 125 // LOW PASS FILTERED
aktk 9:1903c6f8d5a9 126 // Get 10 data and store mean as a sample.
aktk 9:1903c6f8d5a9 127 // After get one original sample, system waits for 0.1 sec,
aktk 9:1903c6f8d5a9 128 // thus it takes 1 sec evry sampling.
aktk 9:1903c6f8d5a9 129 _Sample_Set[i].y = 0;
aktk 9:1903c6f8d5a9 130 for(int j = 0; j < 10; j++) {
aktk 9:1903c6f8d5a9 131 tmp_set.y = g_Sensor_Voltage.read();
aktk 9:1903c6f8d5a9 132 #ifdef DEBUG
aktk 9:1903c6f8d5a9 133 g_Serial_Signal.printf("%f,",tmp_set.y);
aktk 9:1903c6f8d5a9 134 #endif
aktk 9:1903c6f8d5a9 135 _Sample_Set[i].y += (tmp_set.y / 10);
aktk 9:1903c6f8d5a9 136 wait(0.1);
aktk 9:1903c6f8d5a9 137 }
aktk 9:1903c6f8d5a9 138 #ifdef DEBUG
aktk 9:1903c6f8d5a9 139 g_Serial_Signal.printf("(%f)\n",_Sample_Set[i].y);
aktk 9:1903c6f8d5a9 140 #endif
aktk 9:1903c6f8d5a9 141 }
aktk 9:1903c6f8d5a9 142
aktk 9:1903c6f8d5a9 143 // if the input data is over the bound, it is calibrated
aktk 9:1903c6f8d5a9 144 if (_Sample_Set[i].x < 0)
aktk 9:1903c6f8d5a9 145 _Sample_Set[i].x = 0;
aktk 9:1903c6f8d5a9 146 }
aktk 9:1903c6f8d5a9 147 //
aktk 9:1903c6f8d5a9 148 // Sort set data array in x-Ascending order
aktk 9:1903c6f8d5a9 149 //
aktk 9:1903c6f8d5a9 150 tmp = 0;
aktk 9:1903c6f8d5a9 151 for( int i = 0 ; i < _Sample_Num; i++) {
aktk 9:1903c6f8d5a9 152 for(int j = _Sample_Num - 1; i < j ; j--) {
aktk 9:1903c6f8d5a9 153 // use dst as index for dst range [2,20]
aktk 9:1903c6f8d5a9 154 if (_Sample_Set[i].x > _Sample_Set[j].x) {
aktk 9:1903c6f8d5a9 155 tmp_set.x = _Sample_Set[i].x;
aktk 9:1903c6f8d5a9 156 tmp_set.y = _Sample_Set[i].y;
aktk 9:1903c6f8d5a9 157 _Sample_Set[i].x = _Sample_Set[j].x;
aktk 9:1903c6f8d5a9 158 _Sample_Set[i].y = _Sample_Set[j].y;
aktk 9:1903c6f8d5a9 159 _Sample_Set[j].x = tmp_set.x;
aktk 9:1903c6f8d5a9 160 _Sample_Set[j].y = tmp_set.y;
aktk 9:1903c6f8d5a9 161 }
aktk 9:1903c6f8d5a9 162 // if a same dst has been input, calcurate mean.
aktk 9:1903c6f8d5a9 163 else if (_Sample_Set[i].x == _Sample_Set[j].x) {
aktk 9:1903c6f8d5a9 164 tmp_set.y = (_Sample_Set[i].y + _Sample_Set[j].y)/2;
aktk 9:1903c6f8d5a9 165 _Sample_Set[i].y = tmp_set.y;
aktk 9:1903c6f8d5a9 166 for(int k = j; k < _Sample_Num - 1; k++)
aktk 9:1903c6f8d5a9 167 _Sample_Set[k] = _Sample_Set[k+1];
aktk 9:1903c6f8d5a9 168 tmp++;
aktk 9:1903c6f8d5a9 169 }
aktk 9:1903c6f8d5a9 170 }
aktk 9:1903c6f8d5a9 171 }
aktk 9:1903c6f8d5a9 172 #ifdef DEBUG
aktk 9:1903c6f8d5a9 173 g_Serial_Signal.printf(" _Sample_num: %d\n", _Sample_Num );
aktk 9:1903c6f8d5a9 174 g_Serial_Signal.printf("-) tmp: %d\n", tmp );
aktk 9:1903c6f8d5a9 175 #endif
aktk 9:1903c6f8d5a9 176 // substruct tmp from number of sample.
aktk 9:1903c6f8d5a9 177 _Sample_Num -= tmp;
aktk 9:1903c6f8d5a9 178 #ifdef DEBUG
aktk 9:1903c6f8d5a9 179 g_Serial_Signal.printf("-----------------\n");
aktk 9:1903c6f8d5a9 180 g_Serial_Signal.printf(" _Sample_num: %d\n", _Sample_Num );
aktk 9:1903c6f8d5a9 181 #endif
aktk 9:1903c6f8d5a9 182
aktk 9:1903c6f8d5a9 183 // generate t which is parameter related to x,y
aktk 9:1903c6f8d5a9 184 _Sample_Set[0].t = 0;
aktk 9:1903c6f8d5a9 185 for(int i = 1; i < _Sample_Num; i++)
aktk 9:1903c6f8d5a9 186 _Sample_Set[i].t =
aktk 9:1903c6f8d5a9 187 _Sample_Set[i-1].t
aktk 9:1903c6f8d5a9 188 + sqrt(pow(_Sample_Set[i].x - _Sample_Set[i-1].x, 2)
aktk 9:1903c6f8d5a9 189 +pow(_Sample_Set[i].y - _Sample_Set[i-1].y, 2));
aktk 9:1903c6f8d5a9 190 }
aktk 9:1903c6f8d5a9 191
aktk 9:1903c6f8d5a9 192 #define VERSION_C
aktk 9:1903c6f8d5a9 193 #define DEBUG_MAKE_MODEL
aktk 9:1903c6f8d5a9 194 //
aktk 9:1903c6f8d5a9 195 // Function to define _u_spline, specific constants of spline.
aktk 9:1903c6f8d5a9 196 //
aktk 9:1903c6f8d5a9 197 void CubicSpline2d::_makeModel(const double* arg_sampled_t, const double* arg_sampled_ft, double* arg_C[4], const unsigned int arg_num)
aktk 9:1903c6f8d5a9 198 {
aktk 9:1903c6f8d5a9 199 // arg_t : t; The variable of f(t)
aktk 9:1903c6f8d5a9 200 // arg_ft: f(t); The cubic poliminal in Interval-j.
aktk 9:1903c6f8d5a9 201 // arg_C[i]: Ci; The coefficient of t^i of f(t) that defines Spline Model Poliminal f(t).
aktk 9:1903c6f8d5a9 202 // arg_num: j in [0,_Sample_Num-1]; The number of interval.
aktk 9:1903c6f8d5a9 203 // f(t)j = C3j*t^3 + C2j*t^2 + C1j*t + C0j
aktk 9:1903c6f8d5a9 204 //
aktk 9:1903c6f8d5a9 205 // N: max of index <=> (_Sample_Num - 1)
aktk 9:1903c6f8d5a9 206 //
aktk 9:1903c6f8d5a9 207 // u[i] === d^2/dx^2(Spline f)[i]
aktk 9:1903c6f8d5a9 208 // i:[0,N]
aktk 9:1903c6f8d5a9 209 // u[0] = u[N] = 0
aktk 9:1903c6f8d5a9 210 #if defined (VERSION_C)
aktk 9:1903c6f8d5a9 211 double *u = (double*)malloc((arg_num ) * sizeof(double));
aktk 9:1903c6f8d5a9 212 #elif defined (VERSION_Cpp)
aktk 9:1903c6f8d5a9 213 double *u = new double[arg_num];
aktk 9:1903c6f8d5a9 214 #elif defined (VERSION_Cpp11)
aktk 9:1903c6f8d5a9 215 std::array<double,arg_num> u;
aktk 9:1903c6f8d5a9 216 #endif
aktk 9:1903c6f8d5a9 217 //
aktk 9:1903c6f8d5a9 218 // h[i] = x[i+1] - x[i]
aktk 9:1903c6f8d5a9 219 // i:[0,N-1]; num of elm: N<=>_Sample_Num - 1
aktk 9:1903c6f8d5a9 220 double *h = (double*)malloc((arg_num - 1) * sizeof(double));
aktk 9:1903c6f8d5a9 221 //
aktk 9:1903c6f8d5a9 222 // v[i] = 6*((y[i+2]-y[i+1])/h[i+1] + (y[i+1]-y[i])/h[i])
aktk 9:1903c6f8d5a9 223 // i:[0,N-2]
aktk 9:1903c6f8d5a9 224 double *v = (double*)malloc((arg_num - 2) * sizeof(double));
aktk 9:1903c6f8d5a9 225 //
aktk 9:1903c6f8d5a9 226 // temporary array whose num of elm equals v array
aktk 9:1903c6f8d5a9 227 double *w = (double*)malloc((arg_num - 2) * sizeof(double));
aktk 9:1903c6f8d5a9 228 //
aktk 9:1903c6f8d5a9 229 // [ 2(h[0]+h[1]) , h[1] , O ] [u[1] ] [v[0] ]
aktk 9:1903c6f8d5a9 230 // [ h[1] , 2(h[1]+h[2]) , h[2] ] [u[2] ] [v[1] ]
aktk 9:1903c6f8d5a9 231 // [ ... ] * [... ] = [... ]
aktk 9:1903c6f8d5a9 232 // [ h[j] , 2(h[j]+h[j+1]) , h[j+1] ] [u[j+1]] [v[j] ]
aktk 9:1903c6f8d5a9 233 // [ ... ] [ ... ] [ ... ]
aktk 9:1903c6f8d5a9 234 // [ h[N-3] , 2(h[N-3]+h[N-2]), h[N-2] ] [u[j+1]] [v[j] ]
aktk 9:1903c6f8d5a9 235 // [ O h[N-2] , 2(h[N-2]+h[N-1]) ] [u[N-1]] [v[N-2]]
aktk 9:1903c6f8d5a9 236 //
aktk 9:1903c6f8d5a9 237 // For LU decomposition
aktk 9:1903c6f8d5a9 238 double *Upper = (double*)malloc((arg_num - 2) * sizeof(double));
aktk 9:1903c6f8d5a9 239 double *Lower = (double*)malloc((arg_num - 2) * sizeof(double));
aktk 9:1903c6f8d5a9 240 #ifdef DEBUG_MAKE_MODEL
aktk 9:1903c6f8d5a9 241 _printOutDataCouple(arg_sampled_t, arg_sampled_ft, arg_num, "\nargment set\n");
aktk 9:1903c6f8d5a9 242 #endif
aktk 9:1903c6f8d5a9 243
aktk 9:1903c6f8d5a9 244 for(int i = 0; i < arg_num - 1; i++)
aktk 9:1903c6f8d5a9 245 h[i] = (double)(arg_sampled_t[i + 1] - arg_sampled_t[i]);
aktk 9:1903c6f8d5a9 246
aktk 9:1903c6f8d5a9 247 for(int i = 0; i < arg_num - 2; i++)
aktk 9:1903c6f8d5a9 248 v[i] = 6 * (
aktk 9:1903c6f8d5a9 249 ((double)(arg_sampled_ft[i + 2] - arg_sampled_ft[i + 1])) / h[i + 1]
aktk 9:1903c6f8d5a9 250 -
aktk 9:1903c6f8d5a9 251 ((double)(arg_sampled_ft[i + 1] - arg_sampled_ft[i])) / h[i]
aktk 9:1903c6f8d5a9 252 );
aktk 9:1903c6f8d5a9 253
aktk 9:1903c6f8d5a9 254 //
aktk 9:1903c6f8d5a9 255 // LU decomposition
aktk 9:1903c6f8d5a9 256 //
aktk 9:1903c6f8d5a9 257 Upper[0] = 2 * (h[0] + h[1]);
aktk 9:1903c6f8d5a9 258 Lower[0] = 0;
aktk 9:1903c6f8d5a9 259 for (int i = 1; i < arg_num - 2; i++) {
aktk 9:1903c6f8d5a9 260 Lower[i] = h[i] / Upper[i - 1];
aktk 9:1903c6f8d5a9 261 Upper[i] = 2 * (h[i] + h[i + 1]) - Lower[i] * h[i];
aktk 9:1903c6f8d5a9 262 }
aktk 9:1903c6f8d5a9 263 //
aktk 9:1903c6f8d5a9 264 // forward substitution
aktk 9:1903c6f8d5a9 265 //
aktk 9:1903c6f8d5a9 266 w[0] = v[0];
aktk 9:1903c6f8d5a9 267 for (int i = 1; i < arg_num - 2; i ++) {
aktk 9:1903c6f8d5a9 268 w[i] = v[i] - Lower[i] * w[i-1];
aktk 9:1903c6f8d5a9 269 }
aktk 9:1903c6f8d5a9 270 //
aktk 9:1903c6f8d5a9 271 // backward substitution
aktk 9:1903c6f8d5a9 272 //
aktk 9:1903c6f8d5a9 273 u[arg_num - 2] = w[arg_num - 3] / Upper[arg_num - 3];
aktk 9:1903c6f8d5a9 274 for(int i = arg_num - 3; i > 0; i--) {
aktk 9:1903c6f8d5a9 275 u[i] = (w[(i - 1)] - h[(i)] * u[(i) + 1]) / Upper[(i - 1)];
aktk 9:1903c6f8d5a9 276 }
aktk 9:1903c6f8d5a9 277 // _u_spline[i] === d^2/dx^2(Spline f)[i]
aktk 9:1903c6f8d5a9 278 u[0] = u[arg_num - 1] = 0.0;
aktk 9:1903c6f8d5a9 279 #ifdef DEBUG_MAKE_MODEL
aktk 9:1903c6f8d5a9 280 _printOutData(h, arg_num - 1, "h");
aktk 9:1903c6f8d5a9 281 _printOutData(v, arg_num - 2, "v");
aktk 9:1903c6f8d5a9 282 _printOutData(w, arg_num - 2, "w");
aktk 9:1903c6f8d5a9 283 _printOutData(Upper, arg_num - 2, "Upper");
aktk 9:1903c6f8d5a9 284 _printOutData(Lower, arg_num - 2, "Lower");
aktk 9:1903c6f8d5a9 285 _printOutData(u, arg_num , "u");
aktk 9:1903c6f8d5a9 286 #endif
aktk 9:1903c6f8d5a9 287
aktk 9:1903c6f8d5a9 288 for(int ival = 0; ival < arg_num - 1; ival++) {
aktk 9:1903c6f8d5a9 289 arg_C[3][ival] = (u[ival + 1] - u[ival]) / 6.0 / (arg_sampled_t[ival + 1] - arg_sampled_t[ival]);
aktk 9:1903c6f8d5a9 290 arg_C[2][ival] = (u[ival]) / 2.0;
aktk 9:1903c6f8d5a9 291 arg_C[1][ival] = (arg_sampled_ft[ival + 1] - arg_sampled_ft[ival]) / (arg_sampled_t[ival + 1] - arg_sampled_t[ival])
aktk 9:1903c6f8d5a9 292 -
aktk 9:1903c6f8d5a9 293 (arg_sampled_t[ival + 1] - arg_sampled_t[ival]) * (u[ival + 1] + 2.0 * u[ival]) / 6.0;
aktk 9:1903c6f8d5a9 294 arg_C[0][ival] = (arg_sampled_ft[ival]);
aktk 9:1903c6f8d5a9 295 }
aktk 9:1903c6f8d5a9 296 #ifdef DEBUG_MAKE_MODEL
aktk 9:1903c6f8d5a9 297 for(int ival = 0; ival < arg_num - 1; ival++) {
aktk 9:1903c6f8d5a9 298 for(int i = 0; i < 4; i++)
aktk 9:1903c6f8d5a9 299 g_Serial_Signal.printf("C[%d][%d]: %f\n", i, ival, arg_C[i][ival]);
aktk 9:1903c6f8d5a9 300 }
aktk 9:1903c6f8d5a9 301 #endif
aktk 9:1903c6f8d5a9 302
aktk 9:1903c6f8d5a9 303 free(h);
aktk 9:1903c6f8d5a9 304 free(u);
aktk 9:1903c6f8d5a9 305 free(v);
aktk 9:1903c6f8d5a9 306 free(w);
aktk 9:1903c6f8d5a9 307 free(Upper);
aktk 9:1903c6f8d5a9 308 free(Lower);
aktk 9:1903c6f8d5a9 309 }
aktk 9:1903c6f8d5a9 310 void CubicSpline2d::_makeModel(const double* arg_t, const double* arg_ft, double* arg_C[4])
aktk 9:1903c6f8d5a9 311 {
aktk 9:1903c6f8d5a9 312 _makeModel(arg_t, arg_ft, arg_C, _Sample_Num);
aktk 9:1903c6f8d5a9 313 }
aktk 9:1903c6f8d5a9 314 //
aktk 9:1903c6f8d5a9 315 // Fuction to return the value of Cubic polynomial f(t)
aktk 9:1903c6f8d5a9 316 //
aktk 9:1903c6f8d5a9 317 double CubicSpline2d::_cubic_f(const double arg_t, const double arg_C[4])
aktk 9:1903c6f8d5a9 318 {
aktk 9:1903c6f8d5a9 319 double ft; //the value of Spline f(t).
aktk 9:1903c6f8d5a9 320
aktk 9:1903c6f8d5a9 321 ft = arg_C[3] * pow(arg_t, 3) + arg_C[2] * pow(arg_t, 2) + arg_C[1] * arg_t + arg_C[0];
aktk 9:1903c6f8d5a9 322
aktk 9:1903c6f8d5a9 323 return ft;
aktk 9:1903c6f8d5a9 324 }
aktk 9:1903c6f8d5a9 325 //
aktk 9:1903c6f8d5a9 326 // Function to solve a cubic polinomial
aktk 9:1903c6f8d5a9 327 // by using Gardano-Tartaglia formula
aktk 9:1903c6f8d5a9 328 //
aktk 9:1903c6f8d5a9 329 #define DEBUG_SOLVE
aktk 9:1903c6f8d5a9 330 void CubicSpline2d::_solve_cubic_f(
aktk 9:1903c6f8d5a9 331 std::complex<double>* arg_t,
aktk 9:1903c6f8d5a9 332 const double arg_C[4],
aktk 9:1903c6f8d5a9 333 const double arg_ft)
aktk 9:1903c6f8d5a9 334 {
aktk 9:1903c6f8d5a9 335 #ifdef DEBUG_SOLVE
aktk 9:1903c6f8d5a9 336 for(int i = 0; i < 4; i++)
aktk 9:1903c6f8d5a9 337 g_Serial_Signal.printf("C%d: %f\n", i, arg_C[i]);
aktk 9:1903c6f8d5a9 338 #endif
aktk 9:1903c6f8d5a9 339
aktk 9:1903c6f8d5a9 340 double c[3];
aktk 9:1903c6f8d5a9 341 //f(t) = arg_ft/arg_C[3]
aktk 9:1903c6f8d5a9 342 // = t^3 + c[2]*t^2 + c[1]*t + c[0].
aktk 9:1903c6f8d5a9 343 for(int i = 0; i < 3; i++) {
aktk 9:1903c6f8d5a9 344 c[i] = arg_C[i] / arg_C[3];
aktk 9:1903c6f8d5a9 345 }
aktk 9:1903c6f8d5a9 346 //modify the formula
aktk 9:1903c6f8d5a9 347 //t^3 + c[2]*t^2 + c[1]*t + (c[0] - ft) = 0.
aktk 9:1903c6f8d5a9 348 c[0] -= arg_ft / arg_C[3];
aktk 9:1903c6f8d5a9 349 #ifdef DEBUG_SOLVE
aktk 9:1903c6f8d5a9 350 for(int i = 0; i < 3; i++)
aktk 9:1903c6f8d5a9 351 g_Serial_Signal.printf("c%d: %f\n", i, c[i]);
aktk 9:1903c6f8d5a9 352 #endif
aktk 9:1903c6f8d5a9 353
aktk 9:1903c6f8d5a9 354 //The values defined from coefficients of the formula
aktk 9:1903c6f8d5a9 355 //that identify solutions
aktk 9:1903c6f8d5a9 356 double p,q,d;
aktk 9:1903c6f8d5a9 357 p = ( -pow(c[2], 2) + 3 * c[1]) / 9;
aktk 9:1903c6f8d5a9 358 q = (2 * pow(c[2], 3) - 9 * c[2] * c[1] + 27 * c[0]) / 54;
aktk 9:1903c6f8d5a9 359 d = - c[2] / 3;
aktk 9:1903c6f8d5a9 360
aktk 9:1903c6f8d5a9 361 //Discriminant section
aktk 9:1903c6f8d5a9 362 double D;
aktk 9:1903c6f8d5a9 363 D = pow(p, 3) + pow(q, 2);
aktk 9:1903c6f8d5a9 364 #ifdef DEBUG_SOLVE
aktk 9:1903c6f8d5a9 365 g_Serial_Signal.printf("p: %f\n", p);
aktk 9:1903c6f8d5a9 366 g_Serial_Signal.printf("q: %f\n", q);
aktk 9:1903c6f8d5a9 367 g_Serial_Signal.printf("d: %f\n", d);
aktk 9:1903c6f8d5a9 368 g_Serial_Signal.printf("D: %f\n", D);
aktk 9:1903c6f8d5a9 369 #endif
aktk 9:1903c6f8d5a9 370
aktk 9:1903c6f8d5a9 371 //The values defined from p and q
aktk 9:1903c6f8d5a9 372 //that idetify solutions
aktk 9:1903c6f8d5a9 373 std::complex<double> u,v;
aktk 9:1903c6f8d5a9 374
aktk 9:1903c6f8d5a9 375 //Real root only
aktk 9:1903c6f8d5a9 376 if(D <= 0) {
aktk 9:1903c6f8d5a9 377 u = std::complex<double>(-q, sqrt(-D));
aktk 9:1903c6f8d5a9 378 v = std::complex<double>(-q,-sqrt(-D));
aktk 11:a279e31d8499 379 //u = pow(u, 1/3);
aktk 11:a279e31d8499 380 //v = pow(v, 1/3);
aktk 11:a279e31d8499 381 u = std::exp(std::log(u)/3);
aktk 11:a279e31d8499 382 v = std::exp(std::log(u)/3);
aktk 9:1903c6f8d5a9 383 }
aktk 9:1903c6f8d5a9 384 //One real root and two complex root
aktk 9:1903c6f8d5a9 385 else {
aktk 9:1903c6f8d5a9 386 u = std::complex<double>(-q+sqrt(D),0.0);
aktk 9:1903c6f8d5a9 387 v = std::complex<double>(-q-sqrt(D),0.0);
aktk 9:1903c6f8d5a9 388 u = std::complex<double>(cbrt(u.real()), 0.0);
aktk 9:1903c6f8d5a9 389 v = std::complex<double>(cbrt(v.real()), 0.0);
aktk 9:1903c6f8d5a9 390 }
aktk 9:1903c6f8d5a9 391 #ifdef DEBUG_SOLVE
aktk 9:1903c6f8d5a9 392 g_Serial_Signal.printf("u: %f + (%f)i\n", u.real(), u.imag());
aktk 9:1903c6f8d5a9 393 g_Serial_Signal.printf("v: %f + (%f)i\n", v.real(), v.imag());
aktk 9:1903c6f8d5a9 394 #endif
aktk 9:1903c6f8d5a9 395
aktk 9:1903c6f8d5a9 396 //Cubic root of 1
aktk 9:1903c6f8d5a9 397 std::complex<double> omega[3]= {
aktk 9:1903c6f8d5a9 398 std::complex<double>( 1.0, 0.0),
aktk 9:1903c6f8d5a9 399 std::complex<double>(-1/2, sqrt(3.0)/2),
aktk 9:1903c6f8d5a9 400 std::complex<double>(-1/2,-sqrt(3.0)/2)
aktk 9:1903c6f8d5a9 401 };
aktk 9:1903c6f8d5a9 402
aktk 9:1903c6f8d5a9 403 //Solution of the formula
aktk 9:1903c6f8d5a9 404 arg_t[0] = omega[0] * u + omega[0] * v + d;
aktk 9:1903c6f8d5a9 405 arg_t[1] = omega[1] * u + omega[2] * v + d;
aktk 9:1903c6f8d5a9 406 arg_t[2] = omega[2] * u + omega[1] * v + d;
aktk 9:1903c6f8d5a9 407
aktk 9:1903c6f8d5a9 408 #ifdef DEBUG_SOLVE
aktk 9:1903c6f8d5a9 409 for(int i = 0; i < 3; i++)
aktk 9:1903c6f8d5a9 410 g_Serial_Signal.printf("t%d: %f + (%f)i\n", i, arg_t[i].real(), arg_t[i].imag() );
aktk 9:1903c6f8d5a9 411 #endif
aktk 9:1903c6f8d5a9 412 }
aktk 9:1903c6f8d5a9 413
aktk 9:1903c6f8d5a9 414 #define DEBUG_GETX "DEBUG_GETX\n"
aktk 9:1903c6f8d5a9 415 double CubicSpline2d::getX(double arg_y)
aktk 9:1903c6f8d5a9 416 {
aktk 9:1903c6f8d5a9 417 double x;
aktk 9:1903c6f8d5a9 418 double C[4];
aktk 9:1903c6f8d5a9 419 double the_t;
aktk 9:1903c6f8d5a9 420 int the_i;
aktk 9:1903c6f8d5a9 421 std::complex<double>t_sol[3];
aktk 9:1903c6f8d5a9 422 std::vector<double> t_real;
aktk 9:1903c6f8d5a9 423 std::vector<int> t_ival;
aktk 9:1903c6f8d5a9 424
aktk 9:1903c6f8d5a9 425 #ifdef DEBUG_GETX
aktk 9:1903c6f8d5a9 426 g_Serial_Signal.printf(DEBUG_GETX);
aktk 9:1903c6f8d5a9 427 #endif
aktk 9:1903c6f8d5a9 428 // For the every Intervals of Spline,
aktk 9:1903c6f8d5a9 429 //it solves the polynomial defined by C[i] of the interval,
aktk 9:1903c6f8d5a9 430 //checks the solutions are real number,
aktk 9:1903c6f8d5a9 431 //and ckecks the solutions are in the interval.
aktk 9:1903c6f8d5a9 432 // And if not-excluded solutions are more than one,
aktk 9:1903c6f8d5a9 433 //it trys to find which one is more nearest to last point.
aktk 9:1903c6f8d5a9 434 for(int ival = 0; ival < _Sample_Num - 1; ival++) {
aktk 9:1903c6f8d5a9 435 for(int i = 0; i < 4; i++) C[i] = _C_y[i][ival];
aktk 9:1903c6f8d5a9 436 _solve_cubic_f(t_sol, C, arg_y);
aktk 9:1903c6f8d5a9 437 #ifdef DEBUG_GETX
aktk 9:1903c6f8d5a9 438 g_Serial_Signal.printf("interval:%d \t %f < t < %f\n", ival, _Sample_Set[ival].t, _Sample_Set[ival+1].t);
aktk 9:1903c6f8d5a9 439 #endif
aktk 9:1903c6f8d5a9 440 for(int i = 0; i < 3; i++) {
aktk 9:1903c6f8d5a9 441 // regarding only real solution
aktk 9:1903c6f8d5a9 442 // acuracy (error range) is supposed +-10E-3 here(groundless)
aktk 9:1903c6f8d5a9 443 if(std::abs(t_sol[i].imag()) < 0.000001) {
aktk 10:607a68db6303 444 /* if (ival == 0 && t_sol[i].real() < _Sample_Set[ival].t) {
aktk 9:1903c6f8d5a9 445 t_real.push_back(_Sample_Set[ival].t);
aktk 9:1903c6f8d5a9 446 t_ival.push_back(ival);
aktk 9:1903c6f8d5a9 447 } else if (ival == _Sample_Num - 2 && _Sample_Set[ival + 1].t <= t_sol[i].real()) {
aktk 9:1903c6f8d5a9 448 t_real.push_back(_Sample_Set[ival + 1].t);
aktk 9:1903c6f8d5a9 449 t_ival.push_back(ival);
aktk 10:607a68db6303 450 } else*/ if (_Sample_Set[ival].t <= t_sol[i].real() && t_sol[i].real() < _Sample_Set[ival+1].t) {
aktk 9:1903c6f8d5a9 451 t_real.push_back(t_sol[i].real());
aktk 9:1903c6f8d5a9 452 t_ival.push_back(ival);
aktk 9:1903c6f8d5a9 453 }
aktk 9:1903c6f8d5a9 454 #ifdef DEBUG_GETX
aktk 9:1903c6f8d5a9 455 g_Serial_Signal.printf("(t, i) = (%f, %d)\n", t_real[t_real.size() - 1], ival);
aktk 9:1903c6f8d5a9 456 #endif
aktk 9:1903c6f8d5a9 457 }
aktk 9:1903c6f8d5a9 458 }
aktk 9:1903c6f8d5a9 459 }
aktk 9:1903c6f8d5a9 460
aktk 10:607a68db6303 461 if(t_real.size > 0) {
aktk 10:607a68db6303 462 the_t = t_real[0];
aktk 10:607a68db6303 463 the_i = t_ival[0];
aktk 10:607a68db6303 464 //if t's size is bigger than 1
aktk 10:607a68db6303 465 for(int i = 1; i < t_real.size(); i++) {
aktk 10:607a68db6303 466 if(std::abs(t_real[i] - _Last_Point.t) < std::abs(the_t - _Last_Point.t)) {
aktk 10:607a68db6303 467 the_t = t_real[i];
aktk 10:607a68db6303 468 the_i = t_ival[i];
aktk 10:607a68db6303 469 }
aktk 9:1903c6f8d5a9 470 }
aktk 10:607a68db6303 471 } else {
aktk 10:607a68db6303 472 the_t = _Last_Point.t;
aktk 10:607a68db6303 473 for (int i = 0; i < _Sumple_Num - 1; i++)
aktk 10:607a68db6303 474 if(_Sumple_Set[i].t <= the_t && the_t <= _Sample_Set[i+1])
aktk 10:607a68db6303 475 the_i = i;
aktk 9:1903c6f8d5a9 476 }
aktk 9:1903c6f8d5a9 477 for(int i = 0; i < 4; i++) C[i] = _C_x[i][the_i];
aktk 9:1903c6f8d5a9 478 x = _cubic_f(the_t - _Sample_Set[the_i].t, C);
aktk 9:1903c6f8d5a9 479 #ifdef DEBUG_GETX
aktk 9:1903c6f8d5a9 480 g_Serial_Signal.printf("(the_t, the_i):= (%f , %d)\n",the_t, the_i);
aktk 9:1903c6f8d5a9 481 #endif
aktk 9:1903c6f8d5a9 482
aktk 9:1903c6f8d5a9 483 return x;
aktk 9:1903c6f8d5a9 484 }
aktk 9:1903c6f8d5a9 485
aktk 9:1903c6f8d5a9 486 #define DEBUG_GETY "DEBUG_GETY\n"
aktk 9:1903c6f8d5a9 487 double CubicSpline2d::getY(double arg_x)
aktk 9:1903c6f8d5a9 488 {
aktk 9:1903c6f8d5a9 489 double y;
aktk 9:1903c6f8d5a9 490 double C[4];
aktk 9:1903c6f8d5a9 491 double the_t;
aktk 9:1903c6f8d5a9 492 int the_i;
aktk 9:1903c6f8d5a9 493 std::complex<double>t_sol[3];
aktk 9:1903c6f8d5a9 494 std::vector<double> t_real;
aktk 9:1903c6f8d5a9 495 std::vector<int> t_ival;
aktk 9:1903c6f8d5a9 496
aktk 9:1903c6f8d5a9 497 #ifdef DEBUG_GETY
aktk 9:1903c6f8d5a9 498 g_Serial_Signal.printf(DEBUG_GETY);
aktk 9:1903c6f8d5a9 499 #endif
aktk 9:1903c6f8d5a9 500 // For the every Intervals of Spline,
aktk 9:1903c6f8d5a9 501 //it solves the polynomial defined by C[i] of the interval,
aktk 9:1903c6f8d5a9 502 //checks the solutions are real number,
aktk 9:1903c6f8d5a9 503 //and ckecks the solutions are in the interval.
aktk 9:1903c6f8d5a9 504 // And if not-excluded solutions are more than one,
aktk 9:1903c6f8d5a9 505 //it trys to find which one is more nearest to last point.
aktk 9:1903c6f8d5a9 506 for(int ival = 0; ival < _Sample_Num - 1; ival++) {
aktk 9:1903c6f8d5a9 507 for(int i = 0; i < 4; i++) C[i] = _C_x[i][ival];
aktk 9:1903c6f8d5a9 508 _solve_cubic_f(t_sol, C, arg_x);
aktk 9:1903c6f8d5a9 509 for(int i = 0; i < 3; i++) {
aktk 9:1903c6f8d5a9 510 // regarding only real solution
aktk 9:1903c6f8d5a9 511 // acuracy (error range) is supposed +-10E-3 here(groundless)
aktk 9:1903c6f8d5a9 512 if(std::abs(t_sol[i].imag()) < 0.000001) {
aktk 9:1903c6f8d5a9 513 /* */ if (ival == 0 && t_sol[i].real() < _Sample_Set[ival].t) {
aktk 9:1903c6f8d5a9 514 t_real.push_back(_Sample_Set[ival].t);
aktk 9:1903c6f8d5a9 515 t_ival.push_back(ival);
aktk 9:1903c6f8d5a9 516 } else if (ival == _Sample_Num - 2 && _Sample_Set[ival + 1].t <= t_sol[i].real()) {
aktk 9:1903c6f8d5a9 517 t_real.push_back(_Sample_Set[ival + 1].t);
aktk 9:1903c6f8d5a9 518 t_ival.push_back(ival);
aktk 9:1903c6f8d5a9 519 } else if (_Sample_Set[ival].t <= t_sol[i].real() && t_sol[i].real() < _Sample_Set[ival+1].t) {
aktk 9:1903c6f8d5a9 520 t_real.push_back(t_sol[i].real());
aktk 9:1903c6f8d5a9 521 t_ival.push_back(ival);
aktk 9:1903c6f8d5a9 522 }
aktk 9:1903c6f8d5a9 523 }
aktk 9:1903c6f8d5a9 524 }
aktk 9:1903c6f8d5a9 525
aktk 9:1903c6f8d5a9 526
aktk 9:1903c6f8d5a9 527 the_t = t_real[0];
aktk 9:1903c6f8d5a9 528 the_i = t_ival[0];
aktk 9:1903c6f8d5a9 529 //if t's size is bigger than 1
aktk 9:1903c6f8d5a9 530 for(int i = 1; i < t_real.size(); i++) {
aktk 9:1903c6f8d5a9 531 if(std::abs(t_real[i] - _Last_Point.t) < std::abs(the_t - _Last_Point.t)) {
aktk 9:1903c6f8d5a9 532 the_t = t_real[i];
aktk 9:1903c6f8d5a9 533 the_i = t_ival[i];
aktk 9:1903c6f8d5a9 534 }
aktk 9:1903c6f8d5a9 535 }
aktk 9:1903c6f8d5a9 536 }
aktk 9:1903c6f8d5a9 537
aktk 9:1903c6f8d5a9 538 for(int i = 0; i < 4; i++) C[i] = _C_y[i][the_i];
aktk 9:1903c6f8d5a9 539 y = _cubic_f(the_t - _Sample_Set[the_i].t, C);
aktk 9:1903c6f8d5a9 540 #ifdef DEBUG_GETY
aktk 9:1903c6f8d5a9 541 g_Serial_Signal.printf("(the_t, the_i):= (%f , %d)i\n",the_t, the_i);
aktk 9:1903c6f8d5a9 542 #endif
aktk 9:1903c6f8d5a9 543
aktk 9:1903c6f8d5a9 544 return y;
aktk 9:1903c6f8d5a9 545 }
aktk 9:1903c6f8d5a9 546
aktk 9:1903c6f8d5a9 547
aktk 9:1903c6f8d5a9 548 void CubicSpline2d::calibrateSensor()
aktk 9:1903c6f8d5a9 549 {
aktk 9:1903c6f8d5a9 550 double t[_Sample_Num];
aktk 9:1903c6f8d5a9 551 double ft[_Sample_Num];
aktk 9:1903c6f8d5a9 552
aktk 9:1903c6f8d5a9 553 _sampleData();
aktk 9:1903c6f8d5a9 554 _Last_Point = _Sample_Set[0];
aktk 9:1903c6f8d5a9 555
aktk 9:1903c6f8d5a9 556 for(int i = 0; i < _Sample_Num; i++) {
aktk 9:1903c6f8d5a9 557 t[i] = _Sample_Set[i].t;
aktk 9:1903c6f8d5a9 558 ft[i]= _Sample_Set[i].x;
aktk 9:1903c6f8d5a9 559 }
aktk 9:1903c6f8d5a9 560 _makeModel(t,ft,_C_x);
aktk 9:1903c6f8d5a9 561 for(int i = 0; i < _Sample_Num; i++) {
aktk 9:1903c6f8d5a9 562 ft[i]= _Sample_Set[i].y;
aktk 9:1903c6f8d5a9 563 }
aktk 9:1903c6f8d5a9 564 _makeModel(t,ft,_C_y);
aktk 9:1903c6f8d5a9 565
aktk 9:1903c6f8d5a9 566 }
aktk 9:1903c6f8d5a9 567
aktk 9:1903c6f8d5a9 568 void CubicSpline2d::saveSetting()
aktk 9:1903c6f8d5a9 569 {
aktk 9:1903c6f8d5a9 570 FILE *fp;
aktk 9:1903c6f8d5a9 571
aktk 9:1903c6f8d5a9 572 fp = fopen("/local/savedata.log", "wb");
aktk 9:1903c6f8d5a9 573
aktk 9:1903c6f8d5a9 574 // Save _Sample_Num
aktk 9:1903c6f8d5a9 575 fwrite(&_Sample_Num, sizeof(unsigned int), 1, fp);
aktk 9:1903c6f8d5a9 576 fputc(0x3b, fp);
aktk 9:1903c6f8d5a9 577 // Save _Sample_Set
aktk 9:1903c6f8d5a9 578 for(int i = 0; i < _Sample_Num; i++) {
aktk 9:1903c6f8d5a9 579 fwrite(&_Sample_Set[i].x, sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 580 fputc(0x2c, fp);
aktk 9:1903c6f8d5a9 581 fwrite(&_Sample_Set[i].y, sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 582 fputc(0x2c, fp);
aktk 9:1903c6f8d5a9 583 fwrite(&_Sample_Set[i].t, sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 584 fputc(0x3b, fp);
aktk 9:1903c6f8d5a9 585 }
aktk 9:1903c6f8d5a9 586 // Save _C_x
aktk 9:1903c6f8d5a9 587 for(int i = 0; i < _Sample_Num - 1; i++) {
aktk 9:1903c6f8d5a9 588 for(int j = 0; j < 4; j++) {
aktk 9:1903c6f8d5a9 589 fwrite(&_C_x[j][i], sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 590 fputc((j != 3)? 0x2c : 0x3b, fp);
aktk 9:1903c6f8d5a9 591 }
aktk 9:1903c6f8d5a9 592 }
aktk 9:1903c6f8d5a9 593 // Save _C_y
aktk 9:1903c6f8d5a9 594 for(int i = 0; i < _Sample_Num - 1; i++) {
aktk 9:1903c6f8d5a9 595 for(int j = 0; j < 4; j++) {
aktk 9:1903c6f8d5a9 596 fwrite(&_C_y[j][i], sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 597 fputc((j != 3)? 0x2c : 0x3b, fp);
aktk 9:1903c6f8d5a9 598 }
aktk 9:1903c6f8d5a9 599 }
aktk 9:1903c6f8d5a9 600
aktk 9:1903c6f8d5a9 601 fclose(fp);
aktk 9:1903c6f8d5a9 602
aktk 9:1903c6f8d5a9 603 }
aktk 9:1903c6f8d5a9 604
aktk 9:1903c6f8d5a9 605 void CubicSpline2d::saveSetting(
aktk 9:1903c6f8d5a9 606 const char *filename
aktk 9:1903c6f8d5a9 607 )
aktk 9:1903c6f8d5a9 608 {
aktk 9:1903c6f8d5a9 609 FILE *fp;
aktk 9:1903c6f8d5a9 610 char *filepath;
aktk 9:1903c6f8d5a9 611 int fnnum = 0;
aktk 9:1903c6f8d5a9 612
aktk 9:1903c6f8d5a9 613 while (filename[fnnum] != 0) fnnum++;
aktk 9:1903c6f8d5a9 614 filepath = (char *)malloc((fnnum + 8) * sizeof(char)); // "/local/" are 7 char and \0 is 1 char.
aktk 9:1903c6f8d5a9 615
aktk 9:1903c6f8d5a9 616 sprintf(filepath, "/local/%s", filename);
aktk 9:1903c6f8d5a9 617 fp = fopen(filepath, "wb");
aktk 9:1903c6f8d5a9 618
aktk 9:1903c6f8d5a9 619 // Save _Sample_Num
aktk 9:1903c6f8d5a9 620 fwrite(&_Sample_Num, sizeof(unsigned int), 1, fp);
aktk 9:1903c6f8d5a9 621 fputc(0x3b, fp);
aktk 9:1903c6f8d5a9 622 // Save _Sample_Set
aktk 9:1903c6f8d5a9 623 for(int i = 0; i < _Sample_Num; i++) {
aktk 9:1903c6f8d5a9 624 fwrite(&_Sample_Set[i].x, sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 625 fputc(0x2c, fp);
aktk 9:1903c6f8d5a9 626 fwrite(&_Sample_Set[i].y, sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 627 fputc(0x2c, fp);
aktk 9:1903c6f8d5a9 628 fwrite(&_Sample_Set[i].t, sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 629 fputc(0x3b, fp);
aktk 9:1903c6f8d5a9 630 }
aktk 9:1903c6f8d5a9 631 // Save _C_x
aktk 9:1903c6f8d5a9 632 for(int i = 0; i < _Sample_Num - 1; i++) {
aktk 9:1903c6f8d5a9 633 for(int j = 0; j < 4; j++) {
aktk 9:1903c6f8d5a9 634 fwrite(&_C_x[j][i], sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 635 fputc((j != 3)? 0x2c : 0x3b, fp);
aktk 9:1903c6f8d5a9 636 }
aktk 9:1903c6f8d5a9 637 }
aktk 9:1903c6f8d5a9 638 // Save _C_y
aktk 9:1903c6f8d5a9 639 for(int i = 0; i < _Sample_Num - 1; i++) {
aktk 9:1903c6f8d5a9 640 for(int j = 0; j < 4; j++) {
aktk 9:1903c6f8d5a9 641 fwrite(&_C_y[j][i], sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 642 fputc((j != 3)? 0x2c : 0x3b, fp);
aktk 9:1903c6f8d5a9 643 }
aktk 9:1903c6f8d5a9 644 }
aktk 9:1903c6f8d5a9 645
aktk 9:1903c6f8d5a9 646 fclose(fp);
aktk 9:1903c6f8d5a9 647 free(filepath);
aktk 9:1903c6f8d5a9 648 }
aktk 9:1903c6f8d5a9 649
aktk 9:1903c6f8d5a9 650 void CubicSpline2d::loadSetting()
aktk 9:1903c6f8d5a9 651 {
aktk 9:1903c6f8d5a9 652 FILE *fp;
aktk 9:1903c6f8d5a9 653 char tmp;
aktk 9:1903c6f8d5a9 654
aktk 9:1903c6f8d5a9 655 //sprintf(filepath, "/local/%s", filename);
aktk 9:1903c6f8d5a9 656 //fp = fopen(filepath, "rb");
aktk 9:1903c6f8d5a9 657 fp = fopen("/local/savedata.log", "rb");
aktk 9:1903c6f8d5a9 658
aktk 9:1903c6f8d5a9 659 // Load _Sample_Num
aktk 9:1903c6f8d5a9 660 fread(&_Sample_Num, sizeof(unsigned int), 1, fp);
aktk 9:1903c6f8d5a9 661 fread(&tmp, sizeof(char), 1, fp);
aktk 9:1903c6f8d5a9 662
aktk 9:1903c6f8d5a9 663 // Load _Sample_Set
aktk 9:1903c6f8d5a9 664 for(int i = 0; i < _Sample_Num; i++) {
aktk 9:1903c6f8d5a9 665 fread(&_Sample_Set[i].x, sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 666 fread(&tmp, sizeof(char),1,fp);
aktk 9:1903c6f8d5a9 667 fread(&_Sample_Set[i].y, sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 668 fread(&tmp, sizeof(char),1,fp);
aktk 9:1903c6f8d5a9 669 fread(&_Sample_Set[i].t, sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 670 fread(&tmp, sizeof(char),1,fp);
aktk 9:1903c6f8d5a9 671 }
aktk 9:1903c6f8d5a9 672
aktk 9:1903c6f8d5a9 673 // Load _C_x
aktk 9:1903c6f8d5a9 674 for(int i = 0; i < _Sample_Num - 1; i++) {
aktk 9:1903c6f8d5a9 675 for(int j = 0; j < 4; j++) {
aktk 9:1903c6f8d5a9 676 fread(&_C_x[j][i], sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 677 fread(&tmp, sizeof(char),1,fp);
aktk 9:1903c6f8d5a9 678 }
aktk 9:1903c6f8d5a9 679 }
aktk 9:1903c6f8d5a9 680 // Load _C_y
aktk 9:1903c6f8d5a9 681 for(int i = 0; i < _Sample_Num - 1; i++) {
aktk 9:1903c6f8d5a9 682 for(int j = 0; j < 4; j++) {
aktk 9:1903c6f8d5a9 683 fread(&_C_y[j][i], sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 684 fread(&tmp, sizeof(char),1,fp);
aktk 9:1903c6f8d5a9 685 }
aktk 9:1903c6f8d5a9 686 }
aktk 9:1903c6f8d5a9 687 fclose(fp);
aktk 9:1903c6f8d5a9 688 }
aktk 9:1903c6f8d5a9 689
aktk 9:1903c6f8d5a9 690
aktk 9:1903c6f8d5a9 691 void CubicSpline2d::loadSetting(
aktk 9:1903c6f8d5a9 692 const char *filename
aktk 9:1903c6f8d5a9 693 )
aktk 9:1903c6f8d5a9 694 {
aktk 9:1903c6f8d5a9 695 FILE *fp;
aktk 9:1903c6f8d5a9 696 char *filepath;
aktk 9:1903c6f8d5a9 697 char tmp;
aktk 9:1903c6f8d5a9 698 int fnnum = 0;
aktk 9:1903c6f8d5a9 699
aktk 9:1903c6f8d5a9 700 while (filename[fnnum] != 0) fnnum++;
aktk 9:1903c6f8d5a9 701 filepath = (char *)malloc((fnnum + 8) * sizeof(char)); // "/local/" are 7 char and \0 is 1 char.
aktk 9:1903c6f8d5a9 702
aktk 9:1903c6f8d5a9 703 sprintf(filepath, "/local/%s", filename);
aktk 9:1903c6f8d5a9 704 fp = fopen(filepath, "rb");
aktk 9:1903c6f8d5a9 705
aktk 9:1903c6f8d5a9 706 // Load _Sample_Num
aktk 9:1903c6f8d5a9 707 fread(&_Sample_Num, sizeof(unsigned int), 1, fp);
aktk 9:1903c6f8d5a9 708 fread(&tmp, sizeof(char), 1, fp);
aktk 9:1903c6f8d5a9 709
aktk 9:1903c6f8d5a9 710 // Load _Sample_Set
aktk 9:1903c6f8d5a9 711 for(int i = 0; i < _Sample_Num; i++) {
aktk 9:1903c6f8d5a9 712 fread(&_Sample_Set[i].x, sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 713 fread(&tmp, sizeof(char),1,fp);
aktk 9:1903c6f8d5a9 714 fread(&_Sample_Set[i].y, sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 715 fread(&tmp, sizeof(char),1,fp);
aktk 9:1903c6f8d5a9 716 fread(&_Sample_Set[i].t, sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 717 fread(&tmp, sizeof(char),1,fp);
aktk 9:1903c6f8d5a9 718 }
aktk 9:1903c6f8d5a9 719
aktk 9:1903c6f8d5a9 720 // Load _C_x
aktk 9:1903c6f8d5a9 721 for(int i = 0; i < _Sample_Num - 1; i++) {
aktk 9:1903c6f8d5a9 722 for(int j = 0; j < 4; j++) {
aktk 9:1903c6f8d5a9 723 fread(&_C_x[j][i], sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 724 fread(&tmp, sizeof(char),1,fp);
aktk 9:1903c6f8d5a9 725 }
aktk 9:1903c6f8d5a9 726 }
aktk 9:1903c6f8d5a9 727
aktk 9:1903c6f8d5a9 728 // Load _C_y
aktk 9:1903c6f8d5a9 729 for(int i = 0; i < _Sample_Num - 1; i++) {
aktk 9:1903c6f8d5a9 730 for(int j = 0; j < 4; j++) {
aktk 9:1903c6f8d5a9 731 fread(&_C_y[j][i], sizeof(double), 1, fp);
aktk 9:1903c6f8d5a9 732 fread(&tmp, sizeof(char),1,fp);
aktk 9:1903c6f8d5a9 733 }
aktk 9:1903c6f8d5a9 734 }
aktk 9:1903c6f8d5a9 735 fclose(fp);
aktk 9:1903c6f8d5a9 736 free(filepath);
aktk 9:1903c6f8d5a9 737 }
aktk 9:1903c6f8d5a9 738
aktk 9:1903c6f8d5a9 739 void CubicSpline2d::printOutData()
aktk 9:1903c6f8d5a9 740 {
aktk 9:1903c6f8d5a9 741 FILE *fp;
aktk 9:1903c6f8d5a9 742 double d = (_Sample_Set[_Sample_Num - 1].x - _Sample_Set[0].x) / 100;
aktk 9:1903c6f8d5a9 743
aktk 9:1903c6f8d5a9 744 fp = fopen("/local/log.txt", "w"); // open file in writing mode
aktk 9:1903c6f8d5a9 745
aktk 9:1903c6f8d5a9 746 fprintf(fp, "x, y\n");
aktk 9:1903c6f8d5a9 747 for(int ival = 0; ival < _Sample_Num; ival++) {
aktk 9:1903c6f8d5a9 748 for(double x = _Sample_Set[ival].x; x < _Sample_Set[ival+1].x; x += d) {
aktk 9:1903c6f8d5a9 749 fprintf(fp, "%f,%f\n", x, getY(x));
aktk 9:1903c6f8d5a9 750 }
aktk 9:1903c6f8d5a9 751 }
aktk 9:1903c6f8d5a9 752
aktk 9:1903c6f8d5a9 753 fprintf(fp, "\nSample:dst, vol\n");
aktk 9:1903c6f8d5a9 754 for(int i = 0; i < _Sample_Num; i++) {
aktk 9:1903c6f8d5a9 755 fprintf(fp, "%f,%f,(%f)\n", _Sample_Set[i].x, _Sample_Set[i].y, _Sample_Set[i].t);
aktk 9:1903c6f8d5a9 756 }
aktk 9:1903c6f8d5a9 757 fclose(fp);
aktk 9:1903c6f8d5a9 758
aktk 9:1903c6f8d5a9 759 }
aktk 9:1903c6f8d5a9 760 void CubicSpline2d::_printOutData(const double *arg, const int num, const char* name)
aktk 9:1903c6f8d5a9 761 {
aktk 9:1903c6f8d5a9 762 FILE *fp;
aktk 9:1903c6f8d5a9 763
aktk 9:1903c6f8d5a9 764 fp = fopen("/local/varlog.txt", "a"); // open file in add mode
aktk 9:1903c6f8d5a9 765 fprintf(fp, "%10s\n", name);
aktk 9:1903c6f8d5a9 766 for(int i = 0; i < num; i++) {
aktk 9:1903c6f8d5a9 767 fprintf(fp, "%.2f, ", arg[i]);
aktk 9:1903c6f8d5a9 768 }
aktk 9:1903c6f8d5a9 769 fprintf(fp, "\n");
aktk 9:1903c6f8d5a9 770 fclose(fp);
aktk 9:1903c6f8d5a9 771 }
aktk 9:1903c6f8d5a9 772 void CubicSpline2d::_printOutDataCouple(const double *arg1, const double *arg2, const int num, const char* name)
aktk 9:1903c6f8d5a9 773 {
aktk 9:1903c6f8d5a9 774 FILE *fp;
aktk 9:1903c6f8d5a9 775
aktk 9:1903c6f8d5a9 776 fp = fopen("/local/varlog.txt", "a"); // open file in add mode
aktk 9:1903c6f8d5a9 777 fprintf(fp, "%10s\n", name);
aktk 9:1903c6f8d5a9 778 for(int i = 0; i < num; i++) {
aktk 9:1903c6f8d5a9 779 fprintf(fp, "(%.2f, %.2f)\n", arg1[i], arg2[i]);
aktk 9:1903c6f8d5a9 780 }
aktk 9:1903c6f8d5a9 781 fprintf(fp, "\n");
aktk 9:1903c6f8d5a9 782 fclose(fp);
aktk 9:1903c6f8d5a9 783 }
aktk 9:1903c6f8d5a9 784 void CubicSpline2d::_printOutData(const Vxyt *arg, int num, const char* name)
aktk 9:1903c6f8d5a9 785 {
aktk 9:1903c6f8d5a9 786 FILE *fp;
aktk 9:1903c6f8d5a9 787
aktk 9:1903c6f8d5a9 788 fp = fopen("/local/varlog.txt", "a"); // open file in add mode
aktk 9:1903c6f8d5a9 789 fprintf(fp, "%10s\n", name);
aktk 9:1903c6f8d5a9 790 for(int i = 0; i < num; i++) {
aktk 9:1903c6f8d5a9 791 fprintf(fp, "%f, ", arg[i].y);
aktk 9:1903c6f8d5a9 792 }
aktk 9:1903c6f8d5a9 793 fprintf(fp, "\n");
aktk 9:1903c6f8d5a9 794 fclose(fp);
aktk 9:1903c6f8d5a9 795 }