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:
Mon May 30 09:18:50 2016 +0000
Revision:
13:9a51747773af
Parent:
12:b3e07a2220bc
all function has briefly implemented.;

Who changed what in which revision?

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