update credits
[librepilot.git] / flight / libraries / insgps16state.c
blob3516394a7e56e1bfa438c1d89e344302e2f3d83a
1 /**
2 ******************************************************************************
3 * @addtogroup AHRS
4 * @{
5 * @addtogroup INSGPS
6 * @{
7 * @brief INSGPS is a joint attitude and position estimation EKF
9 * @file insgps.c
10 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
11 * @brief An INS/GPS algorithm implemented with an EKF.
13 * @see The GNU Public License (GPL) Version 3
15 *****************************************************************************/
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 3 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 * for more details.
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #include "insgps.h"
33 #include <math.h>
34 #include <stdint.h>
36 // constants/macros/typdefs
37 #define NUMX 16 // number of states, X is the state vector
38 #define NUMW 12 // number of plant noise inputs, w is disturbance noise vector
39 #define NUMV 10 // number of measurements, v is the measurement noise vector
40 #define NUMU 6 // number of deterministic inputs, U is the input vector
42 #if defined(GENERAL_COV)
43 // This might trick people so I have a note here. There is a slower but bigger version of the
44 // code here but won't fit when debugging disabled (requires -Os)
45 #define COVARIANCE_PREDICTION_GENERAL
46 #endif
48 // Private functions
49 void CovariancePrediction(float F[NUMX][NUMX], float G[NUMX][NUMW],
50 float Q[NUMW], float dT, float P[NUMX][NUMX]);
51 void SerialUpdate(float H[NUMV][NUMX], float R[NUMV], float Z[NUMV],
52 float Y[NUMV], float P[NUMX][NUMX], float X[NUMX],
53 uint16_t SensorsUsed);
54 void RungeKutta(float X[NUMX], float U[NUMU], float dT);
55 void StateEq(float X[NUMX], float U[NUMU], float Xdot[NUMX]);
56 void LinearizeFG(float X[NUMX], float U[NUMU], float F[NUMX][NUMX],
57 float G[NUMX][NUMW]);
58 void MeasurementEq(float X[NUMX], float Be[3], float Y[NUMV]);
59 void LinearizeH(float X[NUMX], float Be[3], float H[NUMV][NUMX]);
61 // Private variables
62 float F[NUMX][NUMX], G[NUMX][NUMW], H[NUMV][NUMX]; // linearized system matrices
63 // global to init to zero and maintain zero elements
64 float Be[3]; // local magnetic unit vector in NED frame
65 float P[NUMX][NUMX], X[NUMX]; // covariance matrix and state vector
66 float Q[NUMW], R[NUMV]; // input noise and measurement noise variances
67 float K[NUMX][NUMV]; // feedback gain matrix
69 // ************* Exposed Functions ****************
70 // *************************************************
72 uint16_t ins_get_num_states()
74 return NUMX;
77 void INSGPSInit() // pretty much just a place holder for now
79 Be[0] = 1.0f;
80 Be[1] = 0;
81 Be[2] = 0; // local magnetic unit vector
83 for (int i = 0; i < NUMX; i++) {
84 for (int j = 0; j < NUMX; j++) {
85 P[i][j] = 0.0f; // zero all terms
89 P[0][0] = P[1][1] = P[2][2] = 25.0f; // initial position variance (m^2)
90 P[3][3] = P[4][4] = P[5][5] = 5.0f; // initial velocity variance (m/s)^2
91 P[6][6] = P[7][7] = P[8][8] = P[9][9] = 1e-5f; // initial quaternion variance
92 P[10][10] = P[11][11] = P[12][12] = 1e-5f; // initial gyro bias variance (rad/s)^2
94 X[0] = X[1] = X[2] = X[3] = X[4] = X[5] = 0.0f; // initial pos and vel (m)
95 X[6] = 1.0f;
96 X[7] = X[8] = X[9] = 0.0f; // initial quaternion (level and North) (m/s)
97 X[10] = X[11] = X[12] = 0.0f; // initial gyro bias (rad/s)
99 Q[0] = Q[1] = Q[2] = 50e-8f; // gyro noise variance (rad/s)^2
100 Q[3] = Q[4] = Q[5] = 0.01f; // accelerometer noise variance (m/s^2)^2
101 Q[6] = Q[7] = Q[8] = 2e-9f; // gyro bias random walk variance (rad/s^2)^2
102 Q[9] = Q[10] = Q[11] = 2e-20f; // accel bias random walk variance (m/s^3)^2
104 R[0] = R[1] = 0.004f; // High freq GPS horizontal position noise variance (m^2)
105 R[2] = 0.036f; // High freq GPS vertical position noise variance (m^2)
106 R[3] = R[4] = 0.004f; // High freq GPS horizontal velocity noise variance (m/s)^2
107 R[5] = 100.0f; // High freq GPS vertical velocity noise variance (m/s)^2
108 R[6] = R[7] = R[8] = 0.005f; // magnetometer unit vector noise variance
109 R[9] = .05f; // High freq altimeter noise variance (m^2)
112 void INSResetP(float PDiag[NUMX])
114 uint8_t i, j;
116 // if PDiag[i] nonzero then clear row and column and set diagonal element
117 for (i = 0; i < NUMX; i++) {
118 if (PDiag != 0) {
119 for (j = 0; j < NUMX; j++) {
120 P[i][j] = P[j][i] = 0.0f;
122 P[i][i] = PDiag[i];
127 void INSSetState(float pos[3], float vel[3], float q[4], float gyro_bias[3], float accel_bias[3])
129 Nav.Pos[0] = X[0] = pos[0];
130 Nav.Pos[1] = X[1] = pos[1];
131 Nav.Pos[2] = X[2] = pos[2];
132 Nav.Vel[0] = X[3] = vel[0];
133 Nav.Vel[1] = X[4] = vel[1];
134 Nav.Vel[2] = X[5] = vel[2];
135 Nav.q[0] = X[6] = q[0];
136 Nav.q[1] = X[7] = q[1];
137 Nav.q[2] = X[8] = q[2];
138 Nav.q[3] = X[9] = q[3];
139 Nav.gyro_bias[0] = X[10] = gyro_bias[0];
140 Nav.gyro_bias[1] = X[11] = gyro_bias[1];
141 Nav.gyro_bias[2] = X[12] = gyro_bias[2];
142 Nav.accel_bias[0] = X[13] = accel_bias[0];
143 Nav.accel_bias[1] = X[14] = accel_bias[1];
144 Nav.accel_bias[2] = X[15] = accel_bias[2];
147 void INSPosVelReset(float pos[3], float vel[3])
149 for (int i = 0; i < 6; i++) {
150 for (int j = i; j < NUMX; j++) {
151 P[i][j] = 0.0f; // zero the first 6 rows and columns
152 P[j][i] = 0.0f;
156 P[0][0] = P[1][1] = P[2][2] = 25.0f; // initial position variance (m^2)
157 P[3][3] = P[4][4] = P[5][5] = 5.0f; // initial velocity variance (m/s)^2
159 X[0] = pos[0];
160 X[1] = pos[1];
161 X[2] = pos[2];
162 X[3] = vel[0];
163 X[4] = vel[1];
164 X[5] = vel[2];
167 void INSSetPosVelVar(float PosVar, float VelVar)
169 R[0] = PosVar;
170 R[1] = PosVar;
171 R[2] = PosVar;
172 R[3] = VelVar;
173 R[4] = VelVar;
174 R[5] = PosVar; // Don't change vertical velocity, not measured
177 void INSSetGyroBias(float gyro_bias[3])
179 X[10] = gyro_bias[0];
180 X[11] = gyro_bias[1];
181 X[12] = gyro_bias[2];
184 void INSSetAccelVar(float accel_var[3])
186 Q[3] = accel_var[0];
187 Q[4] = accel_var[1];
188 Q[5] = accel_var[2];
191 void INSSetGyroVar(float gyro_var[3])
193 Q[0] = gyro_var[0];
194 Q[1] = gyro_var[1];
195 Q[2] = gyro_var[2];
198 void INSSetMagVar(float scaled_mag_var[3])
200 R[6] = scaled_mag_var[0];
201 R[7] = scaled_mag_var[1];
202 R[8] = scaled_mag_var[2];
205 void INSSetMagNorth(float B[3])
207 Be[0] = B[0];
208 Be[1] = B[1];
209 Be[2] = B[2];
212 void INSStatePrediction(float gyro_data[3], float accel_data[3], float dT)
214 float U[6];
215 float qmag;
217 // rate gyro inputs in units of rad/s
218 U[0] = gyro_data[0];
219 U[1] = gyro_data[1];
220 U[2] = gyro_data[2];
222 // accelerometer inputs in units of m/s
223 U[3] = accel_data[0];
224 U[4] = accel_data[1];
225 U[5] = accel_data[2];
227 // EKF prediction step
228 LinearizeFG(X, U, F, G);
229 RungeKutta(X, U, dT);
230 qmag = sqrt(X[6] * X[6] + X[7] * X[7] + X[8] * X[8] + X[9] * X[9]);
231 X[6] /= qmag;
232 X[7] /= qmag;
233 X[8] /= qmag;
234 X[9] /= qmag;
235 // CovariancePrediction(F,G,Q,dT,P);
237 // Update Nav solution structure
238 Nav.Pos[0] = X[0];
239 Nav.Pos[1] = X[1];
240 Nav.Pos[2] = X[2];
241 Nav.Vel[0] = X[3];
242 Nav.Vel[1] = X[4];
243 Nav.Vel[2] = X[5];
244 Nav.q[0] = X[6];
245 Nav.q[1] = X[7];
246 Nav.q[2] = X[8];
247 Nav.q[3] = X[9];
248 Nav.gyro_bias[0] = X[10];
249 Nav.gyro_bias[1] = X[11];
250 Nav.gyro_bias[2] = X[12];
253 void INSCovariancePrediction(float dT)
255 CovariancePrediction(F, G, Q, dT, P);
258 float zeros[3] = { 0.0f, 0.0f, 0.0f };
260 void MagCorrection(float mag_data[3])
262 INSCorrection(mag_data, zeros, zeros, zeros[0], MAG_SENSORS);
265 void MagVelBaroCorrection(float mag_data[3], float Vel[3], float BaroAlt)
267 INSCorrection(mag_data, zeros, Vel, BaroAlt,
268 MAG_SENSORS | HORIZ_SENSORS | VERT_SENSORS |
269 BARO_SENSOR);
272 void GpsBaroCorrection(float Pos[3], float Vel[3], float BaroAlt)
274 INSCorrection(zeros, Pos, Vel, BaroAlt,
275 HORIZ_SENSORS | VERT_SENSORS | BARO_SENSOR);
278 void FullCorrection(float mag_data[3], float Pos[3], float Vel[3],
279 float BaroAlt)
281 INSCorrection(mag_data, Pos, Vel, BaroAlt, FULL_SENSORS);
284 void GpsMagCorrection(float mag_data[3], float Pos[3], float Vel[3])
286 INSCorrection(mag_data, Pos, Vel, zeros[0],
287 POS_SENSORS | HORIZ_SENSORS | MAG_SENSORS);
290 void VelBaroCorrection(float Vel[3], float BaroAlt)
292 INSCorrection(zeros, zeros, Vel, BaroAlt,
293 HORIZ_SENSORS | VERT_SENSORS | BARO_SENSOR);
296 void INSCorrection(float mag_data[3], float Pos[3], float Vel[3],
297 float BaroAlt, uint16_t SensorsUsed)
299 float Z[10], Y[10];
300 float Bmag, qmag;
302 // GPS Position in meters and in local NED frame
303 Z[0] = Pos[0];
304 Z[1] = Pos[1];
305 Z[2] = Pos[2];
307 // GPS Velocity in meters and in local NED frame
308 Z[3] = Vel[0];
309 Z[4] = Vel[1];
310 Z[5] = Vel[2];
312 // magnetometer data in any units (use unit vector) and in body frame
313 Bmag =
314 sqrt(mag_data[0] * mag_data[0] + mag_data[1] * mag_data[1] +
315 mag_data[2] * mag_data[2]);
316 Z[6] = mag_data[0] / Bmag;
317 Z[7] = mag_data[1] / Bmag;
318 Z[8] = mag_data[2] / Bmag;
320 // barometric altimeter in meters and in local NED frame
321 Z[9] = BaroAlt;
323 // EKF correction step
324 LinearizeH(X, Be, H);
325 MeasurementEq(X, Be, Y);
326 SerialUpdate(H, R, Z, Y, P, X, SensorsUsed);
327 qmag = sqrt(X[6] * X[6] + X[7] * X[7] + X[8] * X[8] + X[9] * X[9]);
328 X[6] /= qmag;
329 X[7] /= qmag;
330 X[8] /= qmag;
331 X[9] /= qmag;
333 // Update Nav solution structure
334 Nav.Pos[0] = X[0];
335 Nav.Pos[1] = X[1];
336 Nav.Pos[2] = X[2];
337 Nav.Vel[0] = X[3];
338 Nav.Vel[1] = X[4];
339 Nav.Vel[2] = X[5];
340 Nav.q[0] = X[6];
341 Nav.q[1] = X[7];
342 Nav.q[2] = X[8];
343 Nav.q[3] = X[9];
344 Nav.gyro_bias[0] = X[10];
345 Nav.gyro_bias[1] = X[11];
346 Nav.gyro_bias[2] = X[12];
347 Nav.accel_bias[0] = X[13];
348 Nav.accel_bias[1] = X[14];
349 Nav.accel_bias[2] = X[15];
352 // ************* CovariancePrediction *************
353 // Does the prediction step of the Kalman filter for the covariance matrix
354 // Output, Pnew, overwrites P, the input covariance
355 // Pnew = (I+F*T)*P*(I+F*T)' + T^2*G*Q*G'
356 // Q is the discrete time covariance of process noise
357 // Q is vector of the diagonal for a square matrix with
358 // dimensions equal to the number of disturbance noise variables
359 // The General Method is very inefficient,not taking advantage of the sparse F and G
360 // The first Method is very specific to this implementation
361 // ************************************************
363 #ifdef COVARIANCE_PREDICTION_GENERAL
365 void CovariancePrediction(float F[NUMX][NUMX], float G[NUMX][NUMW],
366 float Q[NUMW], float dT, float P[NUMX][NUMX])
368 float Dummy[NUMX][NUMX], dTsq;
369 uint8_t i, j, k;
371 // Pnew = (I+F*T)*P*(I+F*T)' + T^2*G*Q*G' = T^2[(P/T + F*P)*(I/T + F') + G*Q*G')]
373 dTsq = dT * dT;
375 for (i = 0; i < NUMX; i++) { // Calculate Dummy = (P/T +F*P)
376 for (j = 0; j < NUMX; j++) {
377 Dummy[i][j] = P[i][j] / dT;
378 for (k = 0; k < NUMX; k++) {
379 Dummy[i][j] += F[i][k] * P[k][j];
383 for (i = 0; i < NUMX; i++) { // Calculate Pnew = Dummy/T + Dummy*F' + G*Qw*G'
384 for (j = i; j < NUMX; j++) { // Use symmetry, ie only find upper triangular
385 P[i][j] = Dummy[i][j] / dT;
386 for (k = 0; k < NUMX; k++) {
387 P[i][j] += Dummy[i][k] * F[j][k]; // P = Dummy/T + Dummy*F'
389 for (k = 0; k < NUMW; k++) {
390 P[i][j] += Q[k] * G[i][k] * G[j][k]; // P = Dummy/T + Dummy*F' + G*Q*G'
392 P[j][i] = P[i][j] = P[i][j] * dTsq; // Pnew = T^2*P and fill in lower triangular;
397 #else /* ifdef COVARIANCE_PREDICTION_GENERAL */
399 void CovariancePrediction(float F[NUMX][NUMX], float G[NUMX][NUMW],
400 float Q[NUMW], float dT, float P[NUMX][NUMX])
402 float D[NUMX][NUMX], T, Tsq;
403 uint8_t i, j;
405 // Pnew = (I+F*T)*P*(I+F*T)' + T^2*G*Q*G' = scalar expansion from symbolic manipulator
407 T = dT;
408 Tsq = dT * dT;
410 for (i = 0; i < NUMX; i++) { // Create a copy of the upper triangular of P
411 for (j = i; j < NUMX; j++) {
412 D[i][j] = P[i][j];
416 // Brute force calculation of the elements of P
417 P[0][0] = D[3][3] * Tsq + (2 * D[0][3]) * T + D[0][0];
418 P[0][1] = P[1][0] = D[3][4] * Tsq + (D[0][4] + D[1][3]) * T + D[0][1];
419 P[0][2] = P[2][0] = D[3][5] * Tsq + (D[0][5] + D[2][3]) * T + D[0][2];
420 P[0][3] = P[3][0] = (F[3][6] * D[3][6] + F[3][7] * D[3][7] + F[3][8] * D[3][8] + F[3][9] * D[3][9] + F[3][13] * D[3][13] + F[3][14] * D[3][14] + F[3][15] * D[3][15]) * Tsq + (D[3][3] + F[3][6] * D[0][6] + F[3][7] * D[0][7] + F[3][8] * D[0][8] + F[3][9] * D[0][9] + F[3][13] * D[0][13] + F[3][14] * D[0][14] + F[3][15] * D[0][15]) * T + D[0][3];
421 P[0][4] = P[4][0] = (F[4][6] * D[3][6] + F[4][7] * D[3][7] + F[4][8] * D[3][8] + F[4][9] * D[3][9] + F[4][13] * D[3][13] + F[4][14] * D[3][14] + F[4][15] * D[3][15]) * Tsq + (D[3][4] + F[4][6] * D[0][6] + F[4][7] * D[0][7] + F[4][8] * D[0][8] + F[4][9] * D[0][9] + F[4][13] * D[0][13] + F[4][14] * D[0][14] + F[4][15] * D[0][15]) * T + D[0][4];
422 P[0][5] = P[5][0] = (F[5][6] * D[3][6] + F[5][7] * D[3][7] + F[5][8] * D[3][8] + F[5][9] * D[3][9] + F[5][13] * D[3][13] + F[5][14] * D[3][14] + F[5][15] * D[3][15]) * Tsq + (D[3][5] + F[5][6] * D[0][6] + F[5][7] * D[0][7] + F[5][8] * D[0][8] + F[5][9] * D[0][9] + F[5][13] * D[0][13] + F[5][14] * D[0][14] + F[5][15] * D[0][15]) * T + D[0][5];
423 P[0][6] = P[6][0] = (F[6][7] * D[3][7] + F[6][8] * D[3][8] + F[6][9] * D[3][9] + F[6][10] * D[3][10] + F[6][11] * D[3][11] + F[6][12] * D[3][12]) * Tsq + (D[3][6] + F[6][7] * D[0][7] + F[6][8] * D[0][8] + F[6][9] * D[0][9] + F[6][10] * D[0][10] + F[6][11] * D[0][11] + F[6][12] * D[0][12]) * T + D[0][6];
424 P[0][7] = P[7][0] = (F[7][6] * D[3][6] + F[7][8] * D[3][8] + F[7][9] * D[3][9] + F[7][10] * D[3][10] + F[7][11] * D[3][11] + F[7][12] * D[3][12]) * Tsq + (D[3][7] + F[7][6] * D[0][6] + F[7][8] * D[0][8] + F[7][9] * D[0][9] + F[7][10] * D[0][10] + F[7][11] * D[0][11] + F[7][12] * D[0][12]) * T + D[0][7];
425 P[0][8] = P[8][0] = (F[8][6] * D[3][6] + F[8][7] * D[3][7] + F[8][9] * D[3][9] + F[8][10] * D[3][10] + F[8][11] * D[3][11] + F[8][12] * D[3][12]) * Tsq + (D[3][8] + F[8][6] * D[0][6] + F[8][7] * D[0][7] + F[8][9] * D[0][9] + F[8][10] * D[0][10] + F[8][11] * D[0][11] + F[8][12] * D[0][12]) * T + D[0][8];
426 P[0][9] = P[9][0] = (F[9][6] * D[3][6] + F[9][7] * D[3][7] + F[9][8] * D[3][8] + F[9][10] * D[3][10] + F[9][11] * D[3][11] + F[9][12] * D[3][12]) * Tsq + (D[3][9] + F[9][6] * D[0][6] + F[9][7] * D[0][7] + F[9][8] * D[0][8] + F[9][10] * D[0][10] + F[9][11] * D[0][11] + F[9][12] * D[0][12]) * T + D[0][9];
427 P[0][10] = P[10][0] = D[3][10] * T + D[0][10];
428 P[0][11] = P[11][0] = D[3][11] * T + D[0][11];
429 P[0][12] = P[12][0] = D[3][12] * T + D[0][12];
430 P[0][13] = P[13][0] = D[3][13] * T + D[0][13];
431 P[0][14] = P[14][0] = D[3][14] * T + D[0][14];
432 P[0][15] = P[15][0] = D[3][15] * T + D[0][15];
433 P[1][1] = D[4][4] * Tsq + (2 * D[1][4]) * T + D[1][1];
434 P[1][2] = P[2][1] = D[4][5] * Tsq + (D[1][5] + D[2][4]) * T + D[1][2];
435 P[1][3] = P[3][1] = (F[3][6] * D[4][6] + F[3][7] * D[4][7] + F[3][8] * D[4][8] + F[3][9] * D[4][9] + F[3][13] * D[4][13] + F[3][14] * D[4][14] + F[3][15] * D[4][15]) * Tsq + (D[3][4] + F[3][6] * D[1][6] + F[3][7] * D[1][7] + F[3][8] * D[1][8] + F[3][9] * D[1][9] + F[3][13] * D[1][13] + F[3][14] * D[1][14] + F[3][15] * D[1][15]) * T + D[1][3];
436 P[1][4] = P[4][1] = (F[4][6] * D[4][6] + F[4][7] * D[4][7] + F[4][8] * D[4][8] + F[4][9] * D[4][9] + F[4][13] * D[4][13] + F[4][14] * D[4][14] + F[4][15] * D[4][15]) * Tsq + (D[4][4] + F[4][6] * D[1][6] + F[4][7] * D[1][7] + F[4][8] * D[1][8] + F[4][9] * D[1][9] + F[4][13] * D[1][13] + F[4][14] * D[1][14] + F[4][15] * D[1][15]) * T + D[1][4];
437 P[1][5] = P[5][1] = (F[5][6] * D[4][6] + F[5][7] * D[4][7] + F[5][8] * D[4][8] + F[5][9] * D[4][9] + F[5][13] * D[4][13] + F[5][14] * D[4][14] + F[5][15] * D[4][15]) * Tsq + (D[4][5] + F[5][6] * D[1][6] + F[5][7] * D[1][7] + F[5][8] * D[1][8] + F[5][9] * D[1][9] + F[5][13] * D[1][13] + F[5][14] * D[1][14] + F[5][15] * D[1][15]) * T + D[1][5];
438 P[1][6] = P[6][1] = (F[6][7] * D[4][7] + F[6][8] * D[4][8] + F[6][9] * D[4][9] + F[6][10] * D[4][10] + F[6][11] * D[4][11] + F[6][12] * D[4][12]) * Tsq + (D[4][6] + F[6][7] * D[1][7] + F[6][8] * D[1][8] + F[6][9] * D[1][9] + F[6][10] * D[1][10] + F[6][11] * D[1][11] + F[6][12] * D[1][12]) * T + D[1][6];
439 P[1][7] = P[7][1] = (F[7][6] * D[4][6] + F[7][8] * D[4][8] + F[7][9] * D[4][9] + F[7][10] * D[4][10] + F[7][11] * D[4][11] + F[7][12] * D[4][12]) * Tsq + (D[4][7] + F[7][6] * D[1][6] + F[7][8] * D[1][8] + F[7][9] * D[1][9] + F[7][10] * D[1][10] + F[7][11] * D[1][11] + F[7][12] * D[1][12]) * T + D[1][7];
440 P[1][8] = P[8][1] = (F[8][6] * D[4][6] + F[8][7] * D[4][7] + F[8][9] * D[4][9] + F[8][10] * D[4][10] + F[8][11] * D[4][11] + F[8][12] * D[4][12]) * Tsq + (D[4][8] + F[8][6] * D[1][6] + F[8][7] * D[1][7] + F[8][9] * D[1][9] + F[8][10] * D[1][10] + F[8][11] * D[1][11] + F[8][12] * D[1][12]) * T + D[1][8];
441 P[1][9] = P[9][1] = (F[9][6] * D[4][6] + F[9][7] * D[4][7] + F[9][8] * D[4][8] + F[9][10] * D[4][10] + F[9][11] * D[4][11] + F[9][12] * D[4][12]) * Tsq + (D[4][9] + F[9][6] * D[1][6] + F[9][7] * D[1][7] + F[9][8] * D[1][8] + F[9][10] * D[1][10] + F[9][11] * D[1][11] + F[9][12] * D[1][12]) * T + D[1][9];
442 P[1][10] = P[10][1] = D[4][10] * T + D[1][10];
443 P[1][11] = P[11][1] = D[4][11] * T + D[1][11];
444 P[1][12] = P[12][1] = D[4][12] * T + D[1][12];
445 P[1][13] = P[13][1] = D[4][13] * T + D[1][13];
446 P[1][14] = P[14][1] = D[4][14] * T + D[1][14];
447 P[1][15] = P[15][1] = D[4][15] * T + D[1][15];
448 P[2][2] = D[5][5] * Tsq + (2 * D[2][5]) * T + D[2][2];
449 P[2][3] = P[3][2] = (F[3][6] * D[5][6] + F[3][7] * D[5][7] + F[3][8] * D[5][8] + F[3][9] * D[5][9] + F[3][13] * D[5][13] + F[3][14] * D[5][14] + F[3][15] * D[5][15]) * Tsq + (D[3][5] + F[3][6] * D[2][6] + F[3][7] * D[2][7] + F[3][8] * D[2][8] + F[3][9] * D[2][9] + F[3][13] * D[2][13] + F[3][14] * D[2][14] + F[3][15] * D[2][15]) * T + D[2][3];
450 P[2][4] = P[4][2] = (F[4][6] * D[5][6] + F[4][7] * D[5][7] + F[4][8] * D[5][8] + F[4][9] * D[5][9] + F[4][13] * D[5][13] + F[4][14] * D[5][14] + F[4][15] * D[5][15]) * Tsq + (D[4][5] + F[4][6] * D[2][6] + F[4][7] * D[2][7] + F[4][8] * D[2][8] + F[4][9] * D[2][9] + F[4][13] * D[2][13] + F[4][14] * D[2][14] + F[4][15] * D[2][15]) * T + D[2][4];
451 P[2][5] = P[5][2] = (F[5][6] * D[5][6] + F[5][7] * D[5][7] + F[5][8] * D[5][8] + F[5][9] * D[5][9] + F[5][13] * D[5][13] + F[5][14] * D[5][14] + F[5][15] * D[5][15]) * Tsq + (D[5][5] + F[5][6] * D[2][6] + F[5][7] * D[2][7] + F[5][8] * D[2][8] + F[5][9] * D[2][9] + F[5][13] * D[2][13] + F[5][14] * D[2][14] + F[5][15] * D[2][15]) * T + D[2][5];
452 P[2][6] = P[6][2] = (F[6][7] * D[5][7] + F[6][8] * D[5][8] + F[6][9] * D[5][9] + F[6][10] * D[5][10] + F[6][11] * D[5][11] + F[6][12] * D[5][12]) * Tsq + (D[5][6] + F[6][7] * D[2][7] + F[6][8] * D[2][8] + F[6][9] * D[2][9] + F[6][10] * D[2][10] + F[6][11] * D[2][11] + F[6][12] * D[2][12]) * T + D[2][6];
453 P[2][7] = P[7][2] = (F[7][6] * D[5][6] + F[7][8] * D[5][8] + F[7][9] * D[5][9] + F[7][10] * D[5][10] + F[7][11] * D[5][11] + F[7][12] * D[5][12]) * Tsq + (D[5][7] + F[7][6] * D[2][6] + F[7][8] * D[2][8] + F[7][9] * D[2][9] + F[7][10] * D[2][10] + F[7][11] * D[2][11] + F[7][12] * D[2][12]) * T + D[2][7];
454 P[2][8] = P[8][2] = (F[8][6] * D[5][6] + F[8][7] * D[5][7] + F[8][9] * D[5][9] + F[8][10] * D[5][10] + F[8][11] * D[5][11] + F[8][12] * D[5][12]) * Tsq + (D[5][8] + F[8][6] * D[2][6] + F[8][7] * D[2][7] + F[8][9] * D[2][9] + F[8][10] * D[2][10] + F[8][11] * D[2][11] + F[8][12] * D[2][12]) * T + D[2][8];
455 P[2][9] = P[9][2] = (F[9][6] * D[5][6] + F[9][7] * D[5][7] + F[9][8] * D[5][8] + F[9][10] * D[5][10] + F[9][11] * D[5][11] + F[9][12] * D[5][12]) * Tsq + (D[5][9] + F[9][6] * D[2][6] + F[9][7] * D[2][7] + F[9][8] * D[2][8] + F[9][10] * D[2][10] + F[9][11] * D[2][11] + F[9][12] * D[2][12]) * T + D[2][9];
456 P[2][10] = P[10][2] = D[5][10] * T + D[2][10];
457 P[2][11] = P[11][2] = D[5][11] * T + D[2][11];
458 P[2][12] = P[12][2] = D[5][12] * T + D[2][12];
459 P[2][13] = P[13][2] = D[5][13] * T + D[2][13];
460 P[2][14] = P[14][2] = D[5][14] * T + D[2][14];
461 P[2][15] = P[15][2] = D[5][15] * T + D[2][15];
462 P[3][3] = (Q[3] * G[3][3] * G[3][3] + Q[4] * G[3][4] * G[3][4] + Q[5] * G[3][5] * G[3][5] + F[3][9] * (F[3][9] * D[9][9] + F[3][13] * D[9][13] + F[3][14] * D[9][14] + F[3][15] * D[9][15] + F[3][6] * D[6][9] + F[3][7] * D[7][9] + F[3][8] * D[8][9]) + F[3][13] * (F[3][9] * D[9][13] + F[3][13] * D[13][13] + F[3][14] * D[13][14] + F[3][15] * D[13][15] + F[3][6] * D[6][13] + F[3][7] * D[7][13] + F[3][8] * D[8][13]) + F[3][14] * (F[3][9] * D[9][14] + F[3][13] * D[13][14] + F[3][14] * D[14][14] + F[3][15] * D[14][15] + F[3][6] * D[6][14] + F[3][7] * D[7][14] + F[3][8] * D[8][14]) + F[3][15] * (F[3][9] * D[9][15] + F[3][13] * D[13][15] + F[3][14] * D[14][15] + F[3][15] * D[14][15] + F[3][6] * D[6][15] + F[3][7] * D[7][15] + F[3][8] * D[8][15]) + F[3][6] * (F[3][6] * D[6][6] + F[3][7] * D[6][7] + F[3][8] * D[6][8] + F[3][9] * D[6][9] + F[3][13] * D[6][13] + F[3][14] * D[6][14] + F[3][15] * D[6][15]) + F[3][7] * (F[3][6] * D[6][7] + F[3][7] * D[7][7] + F[3][8] * D[7][8] + F[3][9] * D[7][9] + F[3][13] * D[7][13] + F[3][14] * D[7][14] + F[3][15] * D[7][15]) + F[3][8] * (F[3][6] * D[6][8] + F[3][7] * D[7][8] + F[3][8] * D[8][8] + F[3][9] * D[8][9] + F[3][13] * D[8][13] + F[3][14] * D[8][14] + F[3][15] * D[8][15])) * Tsq + (2 * F[3][6] * D[3][6] + 2 * F[3][7] * D[3][7] + 2 * F[3][8] * D[3][8] + 2 * F[3][9] * D[3][9] + 2 * F[3][13] * D[3][13] + 2 * F[3][14] * D[3][14] + 2 * F[3][15] * D[3][15]) * T + D[3][3];
463 P[3][4] = P[4][3] = (F[4][9] * (F[3][9] * D[9][9] + F[3][13] * D[9][13] + F[3][14] * D[9][14] + F[3][15] * D[9][15] + F[3][6] * D[6][9] + F[3][7] * D[7][9] + F[3][8] * D[8][9]) + F[4][13] * (F[3][9] * D[9][13] + F[3][13] * D[13][13] + F[3][14] * D[13][14] + F[3][15] * D[13][15] + F[3][6] * D[6][13] + F[3][7] * D[7][13] + F[3][8] * D[8][13]) + F[4][14] * (F[3][9] * D[9][14] + F[3][13] * D[13][14] + F[3][14] * D[14][14] + F[3][15] * D[14][15] + F[3][6] * D[6][14] + F[3][7] * D[7][14] + F[3][8] * D[8][14]) + F[4][15] * (F[3][9] * D[9][15] + F[3][13] * D[13][15] + F[3][14] * D[14][15] + F[3][15] * D[14][15] + F[3][6] * D[6][15] + F[3][7] * D[7][15] + F[3][8] * D[8][15]) + F[4][6] * (F[3][6] * D[6][6] + F[3][7] * D[6][7] + F[3][8] * D[6][8] + F[3][9] * D[6][9] + F[3][13] * D[6][13] + F[3][14] * D[6][14] + F[3][15] * D[6][15]) + F[4][7] * (F[3][6] * D[6][7] + F[3][7] * D[7][7] + F[3][8] * D[7][8] + F[3][9] * D[7][9] + F[3][13] * D[7][13] + F[3][14] * D[7][14] + F[3][15] * D[7][15]) + F[4][8] * (F[3][6] * D[6][8] + F[3][7] * D[7][8] + F[3][8] * D[8][8] + F[3][9] * D[8][9] + F[3][13] * D[8][13] + F[3][14] * D[8][14] + F[3][15] * D[8][15]) + G[3][3] * G[4][3] * Q[3] + G[3][4] * G[4][4] * Q[4] + G[3][5] * G[4][5] * Q[5]) * Tsq + (F[3][6] * D[4][6] + F[4][6] * D[3][6] + F[3][7] * D[4][7] + F[4][7] * D[3][7] + F[3][8] * D[4][8] + F[4][8] * D[3][8] + F[3][9] * D[4][9] + F[4][9] * D[3][9] + F[3][13] * D[4][13] + F[4][13] * D[3][13] + F[3][14] * D[4][14] + F[4][14] * D[3][14] + F[3][15] * D[4][15] + F[4][15] * D[3][15]) * T + D[3][4];
464 P[3][5] = P[5][3] = (F[5][9] * (F[3][9] * D[9][9] + F[3][13] * D[9][13] + F[3][14] * D[9][14] + F[3][15] * D[9][15] + F[3][6] * D[6][9] + F[3][7] * D[7][9] + F[3][8] * D[8][9]) + F[5][13] * (F[3][9] * D[9][13] + F[3][13] * D[13][13] + F[3][14] * D[13][14] + F[3][15] * D[13][15] + F[3][6] * D[6][13] + F[3][7] * D[7][13] + F[3][8] * D[8][13]) + F[5][14] * (F[3][9] * D[9][14] + F[3][13] * D[13][14] + F[3][14] * D[14][14] + F[3][15] * D[14][15] + F[3][6] * D[6][14] + F[3][7] * D[7][14] + F[3][8] * D[8][14]) + F[5][15] * (F[3][9] * D[9][15] + F[3][13] * D[13][15] + F[3][14] * D[14][15] + F[3][15] * D[14][15] + F[3][6] * D[6][15] + F[3][7] * D[7][15] + F[3][8] * D[8][15]) + F[5][6] * (F[3][6] * D[6][6] + F[3][7] * D[6][7] + F[3][8] * D[6][8] + F[3][9] * D[6][9] + F[3][13] * D[6][13] + F[3][14] * D[6][14] + F[3][15] * D[6][15]) + F[5][7] * (F[3][6] * D[6][7] + F[3][7] * D[7][7] + F[3][8] * D[7][8] + F[3][9] * D[7][9] + F[3][13] * D[7][13] + F[3][14] * D[7][14] + F[3][15] * D[7][15]) + F[5][8] * (F[3][6] * D[6][8] + F[3][7] * D[7][8] + F[3][8] * D[8][8] + F[3][9] * D[8][9] + F[3][13] * D[8][13] + F[3][14] * D[8][14] + F[3][15] * D[8][15]) + G[3][3] * G[5][3] * Q[3] + G[3][4] * G[5][4] * Q[4] + G[3][5] * G[5][5] * Q[5]) * Tsq + (F[3][6] * D[5][6] + F[5][6] * D[3][6] + F[3][7] * D[5][7] + F[5][7] * D[3][7] + F[3][8] * D[5][8] + F[5][8] * D[3][8] + F[3][9] * D[5][9] + F[5][9] * D[3][9] + F[3][13] * D[5][13] + F[5][13] * D[3][13] + F[3][14] * D[5][14] + F[5][14] * D[3][14] + F[3][15] * D[5][15] + F[5][15] * D[3][15]) * T + D[3][5];
465 P[3][6] = P[6][3] = (F[6][9] * (F[3][9] * D[9][9] + F[3][13] * D[9][13] + F[3][14] * D[9][14] + F[3][15] * D[9][15] + F[3][6] * D[6][9] + F[3][7] * D[7][9] + F[3][8] * D[8][9]) + F[6][10] * (F[3][9] * D[9][10] + F[3][13] * D[10][13] + F[3][14] * D[10][14] + F[3][15] * D[10][15] + F[3][6] * D[6][10] + F[3][7] * D[7][10] + F[3][8] * D[8][10]) + F[6][11] * (F[3][9] * D[9][11] + F[3][13] * D[11][13] + F[3][14] * D[11][14] + F[3][15] * D[11][15] + F[3][6] * D[6][11] + F[3][7] * D[7][11] + F[3][8] * D[8][11]) + F[6][12] * (F[3][9] * D[9][12] + F[3][13] * D[12][13] + F[3][14] * D[12][14] + F[3][15] * D[12][15] + F[3][6] * D[6][12] + F[3][7] * D[7][12] + F[3][8] * D[8][12]) + F[6][7] * (F[3][6] * D[6][7] + F[3][7] * D[7][7] + F[3][8] * D[7][8] + F[3][9] * D[7][9] + F[3][13] * D[7][13] + F[3][14] * D[7][14] + F[3][15] * D[7][15]) + F[6][8] * (F[3][6] * D[6][8] + F[3][7] * D[7][8] + F[3][8] * D[8][8] + F[3][9] * D[8][9] + F[3][13] * D[8][13] + F[3][14] * D[8][14] + F[3][15] * D[8][15])) * Tsq + (F[3][6] * D[6][6] + F[3][7] * D[6][7] + F[6][7] * D[3][7] + F[3][8] * D[6][8] + F[6][8] * D[3][8] + F[3][9] * D[6][9] + F[6][9] * D[3][9] + F[6][10] * D[3][10] + F[6][11] * D[3][11] + F[6][12] * D[3][12] + F[3][13] * D[6][13] + F[3][14] * D[6][14] + F[3][15] * D[6][15]) * T + D[3][6];
466 P[3][7] = P[7][3] = (F[7][9] * (F[3][9] * D[9][9] + F[3][13] * D[9][13] + F[3][14] * D[9][14] + F[3][15] * D[9][15] + F[3][6] * D[6][9] + F[3][7] * D[7][9] + F[3][8] * D[8][9]) + F[7][10] * (F[3][9] * D[9][10] + F[3][13] * D[10][13] + F[3][14] * D[10][14] + F[3][15] * D[10][15] + F[3][6] * D[6][10] + F[3][7] * D[7][10] + F[3][8] * D[8][10]) + F[7][11] * (F[3][9] * D[9][11] + F[3][13] * D[11][13] + F[3][14] * D[11][14] + F[3][15] * D[11][15] + F[3][6] * D[6][11] + F[3][7] * D[7][11] + F[3][8] * D[8][11]) + F[7][12] * (F[3][9] * D[9][12] + F[3][13] * D[12][13] + F[3][14] * D[12][14] + F[3][15] * D[12][15] + F[3][6] * D[6][12] + F[3][7] * D[7][12] + F[3][8] * D[8][12]) + F[7][6] * (F[3][6] * D[6][6] + F[3][7] * D[6][7] + F[3][8] * D[6][8] + F[3][9] * D[6][9] + F[3][13] * D[6][13] + F[3][14] * D[6][14] + F[3][15] * D[6][15]) + F[7][8] * (F[3][6] * D[6][8] + F[3][7] * D[7][8] + F[3][8] * D[8][8] + F[3][9] * D[8][9] + F[3][13] * D[8][13] + F[3][14] * D[8][14] + F[3][15] * D[8][15])) * Tsq + (F[3][6] * D[6][7] + F[7][6] * D[3][6] + F[3][7] * D[7][7] + F[3][8] * D[7][8] + F[7][8] * D[3][8] + F[3][9] * D[7][9] + F[7][9] * D[3][9] + F[7][10] * D[3][10] + F[7][11] * D[3][11] + F[7][12] * D[3][12] + F[3][13] * D[7][13] + F[3][14] * D[7][14] + F[3][15] * D[7][15]) * T + D[3][7];
467 P[3][8] = P[8][3] = (F[8][9] * (F[3][9] * D[9][9] + F[3][13] * D[9][13] + F[3][14] * D[9][14] + F[3][15] * D[9][15] + F[3][6] * D[6][9] + F[3][7] * D[7][9] + F[3][8] * D[8][9]) + F[8][10] * (F[3][9] * D[9][10] + F[3][13] * D[10][13] + F[3][14] * D[10][14] + F[3][15] * D[10][15] + F[3][6] * D[6][10] + F[3][7] * D[7][10] + F[3][8] * D[8][10]) + F[8][11] * (F[3][9] * D[9][11] + F[3][13] * D[11][13] + F[3][14] * D[11][14] + F[3][15] * D[11][15] + F[3][6] * D[6][11] + F[3][7] * D[7][11] + F[3][8] * D[8][11]) + F[8][12] * (F[3][9] * D[9][12] + F[3][13] * D[12][13] + F[3][14] * D[12][14] + F[3][15] * D[12][15] + F[3][6] * D[6][12] + F[3][7] * D[7][12] + F[3][8] * D[8][12]) + F[8][6] * (F[3][6] * D[6][6] + F[3][7] * D[6][7] + F[3][8] * D[6][8] + F[3][9] * D[6][9] + F[3][13] * D[6][13] + F[3][14] * D[6][14] + F[3][15] * D[6][15]) + F[8][7] * (F[3][6] * D[6][7] + F[3][7] * D[7][7] + F[3][8] * D[7][8] + F[3][9] * D[7][9] + F[3][13] * D[7][13] + F[3][14] * D[7][14] + F[3][15] * D[7][15])) * Tsq + (F[3][6] * D[6][8] + F[3][7] * D[7][8] + F[8][6] * D[3][6] + F[8][7] * D[3][7] + F[3][8] * D[8][8] + F[3][9] * D[8][9] + F[8][9] * D[3][9] + F[8][10] * D[3][10] + F[8][11] * D[3][11] + F[8][12] * D[3][12] + F[3][13] * D[8][13] + F[3][14] * D[8][14] + F[3][15] * D[8][15]) * T + D[3][8];
468 P[3][9] = P[9][3] = (F[9][10] * (F[3][9] * D[9][10] + F[3][13] * D[10][13] + F[3][14] * D[10][14] + F[3][15] * D[10][15] + F[3][6] * D[6][10] + F[3][7] * D[7][10] + F[3][8] * D[8][10]) + F[9][11] * (F[3][9] * D[9][11] + F[3][13] * D[11][13] + F[3][14] * D[11][14] + F[3][15] * D[11][15] + F[3][6] * D[6][11] + F[3][7] * D[7][11] + F[3][8] * D[8][11]) + F[9][12] * (F[3][9] * D[9][12] + F[3][13] * D[12][13] + F[3][14] * D[12][14] + F[3][15] * D[12][15] + F[3][6] * D[6][12] + F[3][7] * D[7][12] + F[3][8] * D[8][12]) + F[9][6] * (F[3][6] * D[6][6] + F[3][7] * D[6][7] + F[3][8] * D[6][8] + F[3][9] * D[6][9] + F[3][13] * D[6][13] + F[3][14] * D[6][14] + F[3][15] * D[6][15]) + F[9][7] * (F[3][6] * D[6][7] + F[3][7] * D[7][7] + F[3][8] * D[7][8] + F[3][9] * D[7][9] + F[3][13] * D[7][13] + F[3][14] * D[7][14] + F[3][15] * D[7][15]) + F[9][8] * (F[3][6] * D[6][8] + F[3][7] * D[7][8] + F[3][8] * D[8][8] + F[3][9] * D[8][9] + F[3][13] * D[8][13] + F[3][14] * D[8][14] + F[3][15] * D[8][15])) * Tsq + (F[9][6] * D[3][6] + F[9][7] * D[3][7] + F[9][8] * D[3][8] + F[3][9] * D[9][9] + F[9][10] * D[3][10] + F[9][11] * D[3][11] + F[9][12] * D[3][12] + F[3][13] * D[9][13] + F[3][14] * D[9][14] + F[3][15] * D[9][15] + F[3][6] * D[6][9] + F[3][7] * D[7][9] + F[3][8] * D[8][9]) * T + D[3][9];
469 P[3][10] = P[10][3] = (F[3][9] * D[9][10] + F[3][13] * D[10][13] + F[3][14] * D[10][14] + F[3][15] * D[10][15] + F[3][6] * D[6][10] + F[3][7] * D[7][10] + F[3][8] * D[8][10]) * T + D[3][10];
470 P[3][11] = P[11][3] = (F[3][9] * D[9][11] + F[3][13] * D[11][13] + F[3][14] * D[11][14] + F[3][15] * D[11][15] + F[3][6] * D[6][11] + F[3][7] * D[7][11] + F[3][8] * D[8][11]) * T + D[3][11];
471 P[3][12] = P[12][3] = (F[3][9] * D[9][12] + F[3][13] * D[12][13] + F[3][14] * D[12][14] + F[3][15] * D[12][15] + F[3][6] * D[6][12] + F[3][7] * D[7][12] + F[3][8] * D[8][12]) * T + D[3][12];
472 P[3][13] = P[13][3] = (F[3][9] * D[9][13] + F[3][13] * D[13][13] + F[3][14] * D[13][14] + F[3][15] * D[13][15] + F[3][6] * D[6][13] + F[3][7] * D[7][13] + F[3][8] * D[8][13]) * T + D[3][13];
473 P[3][14] = P[14][3] = (F[3][9] * D[9][14] + F[3][13] * D[13][14] + F[3][14] * D[14][14] + F[3][15] * D[14][15] + F[3][6] * D[6][14] + F[3][7] * D[7][14] + F[3][8] * D[8][14]) * T + D[3][14];
474 P[3][15] = P[15][3] = (F[3][9] * D[9][15] + F[3][13] * D[13][15] + F[3][14] * D[14][15] + F[3][15] * D[14][15] + F[3][6] * D[6][15] + F[3][7] * D[7][15] + F[3][8] * D[8][15]) * T + D[3][15];
475 P[4][4] = (Q[3] * G[4][3] * G[4][3] + Q[4] * G[4][4] * G[4][4] + Q[5] * G[4][5] * G[4][5] + F[4][9] * (F[4][9] * D[9][9] + F[4][13] * D[9][13] + F[4][14] * D[9][14] + F[4][15] * D[9][15] + F[4][6] * D[6][9] + F[4][7] * D[7][9] + F[4][8] * D[8][9]) + F[4][13] * (F[4][9] * D[9][13] + F[4][13] * D[13][13] + F[4][14] * D[13][14] + F[4][15] * D[13][15] + F[4][6] * D[6][13] + F[4][7] * D[7][13] + F[4][8] * D[8][13]) + F[4][14] * (F[4][9] * D[9][14] + F[4][13] * D[13][14] + F[4][14] * D[14][14] + F[4][15] * D[14][15] + F[4][6] * D[6][14] + F[4][7] * D[7][14] + F[4][8] * D[8][14]) + F[4][15] * (F[4][9] * D[9][15] + F[4][13] * D[13][15] + F[4][14] * D[14][15] + F[4][15] * D[14][15] + F[4][6] * D[6][15] + F[4][7] * D[7][15] + F[4][8] * D[8][15]) + F[4][6] * (F[4][6] * D[6][6] + F[4][7] * D[6][7] + F[4][8] * D[6][8] + F[4][9] * D[6][9] + F[4][13] * D[6][13] + F[4][14] * D[6][14] + F[4][15] * D[6][15]) + F[4][7] * (F[4][6] * D[6][7] + F[4][7] * D[7][7] + F[4][8] * D[7][8] + F[4][9] * D[7][9] + F[4][13] * D[7][13] + F[4][14] * D[7][14] + F[4][15] * D[7][15]) + F[4][8] * (F[4][6] * D[6][8] + F[4][7] * D[7][8] + F[4][8] * D[8][8] + F[4][9] * D[8][9] + F[4][13] * D[8][13] + F[4][14] * D[8][14] + F[4][15] * D[8][15])) * Tsq + (2 * F[4][6] * D[4][6] + 2 * F[4][7] * D[4][7] + 2 * F[4][8] * D[4][8] + 2 * F[4][9] * D[4][9] + 2 * F[4][13] * D[4][13] + 2 * F[4][14] * D[4][14] + 2 * F[4][15] * D[4][15]) * T + D[4][4];
476 P[4][5] = P[5][4] = (F[5][9] * (F[4][9] * D[9][9] + F[4][13] * D[9][13] + F[4][14] * D[9][14] + F[4][15] * D[9][15] + F[4][6] * D[6][9] + F[4][7] * D[7][9] + F[4][8] * D[8][9]) + F[5][13] * (F[4][9] * D[9][13] + F[4][13] * D[13][13] + F[4][14] * D[13][14] + F[4][15] * D[13][15] + F[4][6] * D[6][13] + F[4][7] * D[7][13] + F[4][8] * D[8][13]) + F[5][14] * (F[4][9] * D[9][14] + F[4][13] * D[13][14] + F[4][14] * D[14][14] + F[4][15] * D[14][15] + F[4][6] * D[6][14] + F[4][7] * D[7][14] + F[4][8] * D[8][14]) + F[5][15] * (F[4][9] * D[9][15] + F[4][13] * D[13][15] + F[4][14] * D[14][15] + F[4][15] * D[14][15] + F[4][6] * D[6][15] + F[4][7] * D[7][15] + F[4][8] * D[8][15]) + F[5][6] * (F[4][6] * D[6][6] + F[4][7] * D[6][7] + F[4][8] * D[6][8] + F[4][9] * D[6][9] + F[4][13] * D[6][13] + F[4][14] * D[6][14] + F[4][15] * D[6][15]) + F[5][7] * (F[4][6] * D[6][7] + F[4][7] * D[7][7] + F[4][8] * D[7][8] + F[4][9] * D[7][9] + F[4][13] * D[7][13] + F[4][14] * D[7][14] + F[4][15] * D[7][15]) + F[5][8] * (F[4][6] * D[6][8] + F[4][7] * D[7][8] + F[4][8] * D[8][8] + F[4][9] * D[8][9] + F[4][13] * D[8][13] + F[4][14] * D[8][14] + F[4][15] * D[8][15]) + G[4][3] * G[5][3] * Q[3] + G[4][4] * G[5][4] * Q[4] + G[4][5] * G[5][5] * Q[5]) * Tsq + (F[4][6] * D[5][6] + F[5][6] * D[4][6] + F[4][7] * D[5][7] + F[5][7] * D[4][7] + F[4][8] * D[5][8] + F[5][8] * D[4][8] + F[4][9] * D[5][9] + F[5][9] * D[4][9] + F[4][13] * D[5][13] + F[5][13] * D[4][13] + F[4][14] * D[5][14] + F[5][14] * D[4][14] + F[4][15] * D[5][15] + F[5][15] * D[4][15]) * T + D[4][5];
477 P[4][6] = P[6][4] = (F[6][9] * (F[4][9] * D[9][9] + F[4][13] * D[9][13] + F[4][14] * D[9][14] + F[4][15] * D[9][15] + F[4][6] * D[6][9] + F[4][7] * D[7][9] + F[4][8] * D[8][9]) + F[6][10] * (F[4][9] * D[9][10] + F[4][13] * D[10][13] + F[4][14] * D[10][14] + F[4][15] * D[10][15] + F[4][6] * D[6][10] + F[4][7] * D[7][10] + F[4][8] * D[8][10]) + F[6][11] * (F[4][9] * D[9][11] + F[4][13] * D[11][13] + F[4][14] * D[11][14] + F[4][15] * D[11][15] + F[4][6] * D[6][11] + F[4][7] * D[7][11] + F[4][8] * D[8][11]) + F[6][12] * (F[4][9] * D[9][12] + F[4][13] * D[12][13] + F[4][14] * D[12][14] + F[4][15] * D[12][15] + F[4][6] * D[6][12] + F[4][7] * D[7][12] + F[4][8] * D[8][12]) + F[6][7] * (F[4][6] * D[6][7] + F[4][7] * D[7][7] + F[4][8] * D[7][8] + F[4][9] * D[7][9] + F[4][13] * D[7][13] + F[4][14] * D[7][14] + F[4][15] * D[7][15]) + F[6][8] * (F[4][6] * D[6][8] + F[4][7] * D[7][8] + F[4][8] * D[8][8] + F[4][9] * D[8][9] + F[4][13] * D[8][13] + F[4][14] * D[8][14] + F[4][15] * D[8][15])) * Tsq + (F[4][6] * D[6][6] + F[4][7] * D[6][7] + F[6][7] * D[4][7] + F[4][8] * D[6][8] + F[6][8] * D[4][8] + F[4][9] * D[6][9] + F[6][9] * D[4][9] + F[6][10] * D[4][10] + F[6][11] * D[4][11] + F[6][12] * D[4][12] + F[4][13] * D[6][13] + F[4][14] * D[6][14] + F[4][15] * D[6][15]) * T + D[4][6];
478 P[4][7] = P[7][4] = (F[7][9] * (F[4][9] * D[9][9] + F[4][13] * D[9][13] + F[4][14] * D[9][14] + F[4][15] * D[9][15] + F[4][6] * D[6][9] + F[4][7] * D[7][9] + F[4][8] * D[8][9]) + F[7][10] * (F[4][9] * D[9][10] + F[4][13] * D[10][13] + F[4][14] * D[10][14] + F[4][15] * D[10][15] + F[4][6] * D[6][10] + F[4][7] * D[7][10] + F[4][8] * D[8][10]) + F[7][11] * (F[4][9] * D[9][11] + F[4][13] * D[11][13] + F[4][14] * D[11][14] + F[4][15] * D[11][15] + F[4][6] * D[6][11] + F[4][7] * D[7][11] + F[4][8] * D[8][11]) + F[7][12] * (F[4][9] * D[9][12] + F[4][13] * D[12][13] + F[4][14] * D[12][14] + F[4][15] * D[12][15] + F[4][6] * D[6][12] + F[4][7] * D[7][12] + F[4][8] * D[8][12]) + F[7][6] * (F[4][6] * D[6][6] + F[4][7] * D[6][7] + F[4][8] * D[6][8] + F[4][9] * D[6][9] + F[4][13] * D[6][13] + F[4][14] * D[6][14] + F[4][15] * D[6][15]) + F[7][8] * (F[4][6] * D[6][8] + F[4][7] * D[7][8] + F[4][8] * D[8][8] + F[4][9] * D[8][9] + F[4][13] * D[8][13] + F[4][14] * D[8][14] + F[4][15] * D[8][15])) * Tsq + (F[4][6] * D[6][7] + F[7][6] * D[4][6] + F[4][7] * D[7][7] + F[4][8] * D[7][8] + F[7][8] * D[4][8] + F[4][9] * D[7][9] + F[7][9] * D[4][9] + F[7][10] * D[4][10] + F[7][11] * D[4][11] + F[7][12] * D[4][12] + F[4][13] * D[7][13] + F[4][14] * D[7][14] + F[4][15] * D[7][15]) * T + D[4][7];
479 P[4][8] = P[8][4] = (F[8][9] * (F[4][9] * D[9][9] + F[4][13] * D[9][13] + F[4][14] * D[9][14] + F[4][15] * D[9][15] + F[4][6] * D[6][9] + F[4][7] * D[7][9] + F[4][8] * D[8][9]) + F[8][10] * (F[4][9] * D[9][10] + F[4][13] * D[10][13] + F[4][14] * D[10][14] + F[4][15] * D[10][15] + F[4][6] * D[6][10] + F[4][7] * D[7][10] + F[4][8] * D[8][10]) + F[8][11] * (F[4][9] * D[9][11] + F[4][13] * D[11][13] + F[4][14] * D[11][14] + F[4][15] * D[11][15] + F[4][6] * D[6][11] + F[4][7] * D[7][11] + F[4][8] * D[8][11]) + F[8][12] * (F[4][9] * D[9][12] + F[4][13] * D[12][13] + F[4][14] * D[12][14] + F[4][15] * D[12][15] + F[4][6] * D[6][12] + F[4][7] * D[7][12] + F[4][8] * D[8][12]) + F[8][6] * (F[4][6] * D[6][6] + F[4][7] * D[6][7] + F[4][8] * D[6][8] + F[4][9] * D[6][9] + F[4][13] * D[6][13] + F[4][14] * D[6][14] + F[4][15] * D[6][15]) + F[8][7] * (F[4][6] * D[6][7] + F[4][7] * D[7][7] + F[4][8] * D[7][8] + F[4][9] * D[7][9] + F[4][13] * D[7][13] + F[4][14] * D[7][14] + F[4][15] * D[7][15])) * Tsq + (F[4][6] * D[6][8] + F[4][7] * D[7][8] + F[8][6] * D[4][6] + F[8][7] * D[4][7] + F[4][8] * D[8][8] + F[4][9] * D[8][9] + F[8][9] * D[4][9] + F[8][10] * D[4][10] + F[8][11] * D[4][11] + F[8][12] * D[4][12] + F[4][13] * D[8][13] + F[4][14] * D[8][14] + F[4][15] * D[8][15]) * T + D[4][8];
480 P[4][9] = P[9][4] = (F[9][10] * (F[4][9] * D[9][10] + F[4][13] * D[10][13] + F[4][14] * D[10][14] + F[4][15] * D[10][15] + F[4][6] * D[6][10] + F[4][7] * D[7][10] + F[4][8] * D[8][10]) + F[9][11] * (F[4][9] * D[9][11] + F[4][13] * D[11][13] + F[4][14] * D[11][14] + F[4][15] * D[11][15] + F[4][6] * D[6][11] + F[4][7] * D[7][11] + F[4][8] * D[8][11]) + F[9][12] * (F[4][9] * D[9][12] + F[4][13] * D[12][13] + F[4][14] * D[12][14] + F[4][15] * D[12][15] + F[4][6] * D[6][12] + F[4][7] * D[7][12] + F[4][8] * D[8][12]) + F[9][6] * (F[4][6] * D[6][6] + F[4][7] * D[6][7] + F[4][8] * D[6][8] + F[4][9] * D[6][9] + F[4][13] * D[6][13] + F[4][14] * D[6][14] + F[4][15] * D[6][15]) + F[9][7] * (F[4][6] * D[6][7] + F[4][7] * D[7][7] + F[4][8] * D[7][8] + F[4][9] * D[7][9] + F[4][13] * D[7][13] + F[4][14] * D[7][14] + F[4][15] * D[7][15]) + F[9][8] * (F[4][6] * D[6][8] + F[4][7] * D[7][8] + F[4][8] * D[8][8] + F[4][9] * D[8][9] + F[4][13] * D[8][13] + F[4][14] * D[8][14] + F[4][15] * D[8][15])) * Tsq + (F[9][6] * D[4][6] + F[9][7] * D[4][7] + F[9][8] * D[4][8] + F[4][9] * D[9][9] + F[9][10] * D[4][10] + F[9][11] * D[4][11] + F[9][12] * D[4][12] + F[4][13] * D[9][13] + F[4][14] * D[9][14] + F[4][15] * D[9][15] + F[4][6] * D[6][9] + F[4][7] * D[7][9] + F[4][8] * D[8][9]) * T + D[4][9];
481 P[4][10] = P[10][4] = (F[4][9] * D[9][10] + F[4][13] * D[10][13] + F[4][14] * D[10][14] + F[4][15] * D[10][15] + F[4][6] * D[6][10] + F[4][7] * D[7][10] + F[4][8] * D[8][10]) * T + D[4][10];
482 P[4][11] = P[11][4] = (F[4][9] * D[9][11] + F[4][13] * D[11][13] + F[4][14] * D[11][14] + F[4][15] * D[11][15] + F[4][6] * D[6][11] + F[4][7] * D[7][11] + F[4][8] * D[8][11]) * T + D[4][11];
483 P[4][12] = P[12][4] = (F[4][9] * D[9][12] + F[4][13] * D[12][13] + F[4][14] * D[12][14] + F[4][15] * D[12][15] + F[4][6] * D[6][12] + F[4][7] * D[7][12] + F[4][8] * D[8][12]) * T + D[4][12];
484 P[4][13] = P[13][4] = (F[4][9] * D[9][13] + F[4][13] * D[13][13] + F[4][14] * D[13][14] + F[4][15] * D[13][15] + F[4][6] * D[6][13] + F[4][7] * D[7][13] + F[4][8] * D[8][13]) * T + D[4][13];
485 P[4][14] = P[14][4] = (F[4][9] * D[9][14] + F[4][13] * D[13][14] + F[4][14] * D[14][14] + F[4][15] * D[14][15] + F[4][6] * D[6][14] + F[4][7] * D[7][14] + F[4][8] * D[8][14]) * T + D[4][14];
486 P[4][15] = P[15][4] = (F[4][9] * D[9][15] + F[4][13] * D[13][15] + F[4][14] * D[14][15] + F[4][15] * D[14][15] + F[4][6] * D[6][15] + F[4][7] * D[7][15] + F[4][8] * D[8][15]) * T + D[4][15];
487 P[5][5] = (Q[3] * G[5][3] * G[5][3] + Q[4] * G[5][4] * G[5][4] + Q[5] * G[5][5] * G[5][5] + F[5][9] * (F[5][9] * D[9][9] + F[5][13] * D[9][13] + F[5][14] * D[9][14] + F[5][15] * D[9][15] + F[5][6] * D[6][9] + F[5][7] * D[7][9] + F[5][8] * D[8][9]) + F[5][13] * (F[5][9] * D[9][13] + F[5][13] * D[13][13] + F[5][14] * D[13][14] + F[5][15] * D[13][15] + F[5][6] * D[6][13] + F[5][7] * D[7][13] + F[5][8] * D[8][13]) + F[5][14] * (F[5][9] * D[9][14] + F[5][13] * D[13][14] + F[5][14] * D[14][14] + F[5][15] * D[14][15] + F[5][6] * D[6][14] + F[5][7] * D[7][14] + F[5][8] * D[8][14]) + F[5][15] * (F[5][9] * D[9][15] + F[5][13] * D[13][15] + F[5][14] * D[14][15] + F[5][15] * D[14][15] + F[5][6] * D[6][15] + F[5][7] * D[7][15] + F[5][8] * D[8][15]) + F[5][6] * (F[5][6] * D[6][6] + F[5][7] * D[6][7] + F[5][8] * D[6][8] + F[5][9] * D[6][9] + F[5][13] * D[6][13] + F[5][14] * D[6][14] + F[5][15] * D[6][15]) + F[5][7] * (F[5][6] * D[6][7] + F[5][7] * D[7][7] + F[5][8] * D[7][8] + F[5][9] * D[7][9] + F[5][13] * D[7][13] + F[5][14] * D[7][14] + F[5][15] * D[7][15]) + F[5][8] * (F[5][6] * D[6][8] + F[5][7] * D[7][8] + F[5][8] * D[8][8] + F[5][9] * D[8][9] + F[5][13] * D[8][13] + F[5][14] * D[8][14] + F[5][15] * D[8][15])) * Tsq + (2 * F[5][6] * D[5][6] + 2 * F[5][7] * D[5][7] + 2 * F[5][8] * D[5][8] + 2 * F[5][9] * D[5][9] + 2 * F[5][13] * D[5][13] + 2 * F[5][14] * D[5][14] + 2 * F[5][15] * D[5][15]) * T + D[5][5];
488 P[5][6] = P[6][5] = (F[6][9] * (F[5][9] * D[9][9] + F[5][13] * D[9][13] + F[5][14] * D[9][14] + F[5][15] * D[9][15] + F[5][6] * D[6][9] + F[5][7] * D[7][9] + F[5][8] * D[8][9]) + F[6][10] * (F[5][9] * D[9][10] + F[5][13] * D[10][13] + F[5][14] * D[10][14] + F[5][15] * D[10][15] + F[5][6] * D[6][10] + F[5][7] * D[7][10] + F[5][8] * D[8][10]) + F[6][11] * (F[5][9] * D[9][11] + F[5][13] * D[11][13] + F[5][14] * D[11][14] + F[5][15] * D[11][15] + F[5][6] * D[6][11] + F[5][7] * D[7][11] + F[5][8] * D[8][11]) + F[6][12] * (F[5][9] * D[9][12] + F[5][13] * D[12][13] + F[5][14] * D[12][14] + F[5][15] * D[12][15] + F[5][6] * D[6][12] + F[5][7] * D[7][12] + F[5][8] * D[8][12]) + F[6][7] * (F[5][6] * D[6][7] + F[5][7] * D[7][7] + F[5][8] * D[7][8] + F[5][9] * D[7][9] + F[5][13] * D[7][13] + F[5][14] * D[7][14] + F[5][15] * D[7][15]) + F[6][8] * (F[5][6] * D[6][8] + F[5][7] * D[7][8] + F[5][8] * D[8][8] + F[5][9] * D[8][9] + F[5][13] * D[8][13] + F[5][14] * D[8][14] + F[5][15] * D[8][15])) * Tsq + (F[5][6] * D[6][6] + F[5][7] * D[6][7] + F[6][7] * D[5][7] + F[5][8] * D[6][8] + F[6][8] * D[5][8] + F[5][9] * D[6][9] + F[6][9] * D[5][9] + F[6][10] * D[5][10] + F[6][11] * D[5][11] + F[6][12] * D[5][12] + F[5][13] * D[6][13] + F[5][14] * D[6][14] + F[5][15] * D[6][15]) * T + D[5][6];
489 P[5][7] = P[7][5] = (F[7][9] * (F[5][9] * D[9][9] + F[5][13] * D[9][13] + F[5][14] * D[9][14] + F[5][15] * D[9][15] + F[5][6] * D[6][9] + F[5][7] * D[7][9] + F[5][8] * D[8][9]) + F[7][10] * (F[5][9] * D[9][10] + F[5][13] * D[10][13] + F[5][14] * D[10][14] + F[5][15] * D[10][15] + F[5][6] * D[6][10] + F[5][7] * D[7][10] + F[5][8] * D[8][10]) + F[7][11] * (F[5][9] * D[9][11] + F[5][13] * D[11][13] + F[5][14] * D[11][14] + F[5][15] * D[11][15] + F[5][6] * D[6][11] + F[5][7] * D[7][11] + F[5][8] * D[8][11]) + F[7][12] * (F[5][9] * D[9][12] + F[5][13] * D[12][13] + F[5][14] * D[12][14] + F[5][15] * D[12][15] + F[5][6] * D[6][12] + F[5][7] * D[7][12] + F[5][8] * D[8][12]) + F[7][6] * (F[5][6] * D[6][6] + F[5][7] * D[6][7] + F[5][8] * D[6][8] + F[5][9] * D[6][9] + F[5][13] * D[6][13] + F[5][14] * D[6][14] + F[5][15] * D[6][15]) + F[7][8] * (F[5][6] * D[6][8] + F[5][7] * D[7][8] + F[5][8] * D[8][8] + F[5][9] * D[8][9] + F[5][13] * D[8][13] + F[5][14] * D[8][14] + F[5][15] * D[8][15])) * Tsq + (F[5][6] * D[6][7] + F[7][6] * D[5][6] + F[5][7] * D[7][7] + F[5][8] * D[7][8] + F[7][8] * D[5][8] + F[5][9] * D[7][9] + F[7][9] * D[5][9] + F[7][10] * D[5][10] + F[7][11] * D[5][11] + F[7][12] * D[5][12] + F[5][13] * D[7][13] + F[5][14] * D[7][14] + F[5][15] * D[7][15]) * T + D[5][7];
490 P[5][8] = P[8][5] = (F[8][9] * (F[5][9] * D[9][9] + F[5][13] * D[9][13] + F[5][14] * D[9][14] + F[5][15] * D[9][15] + F[5][6] * D[6][9] + F[5][7] * D[7][9] + F[5][8] * D[8][9]) + F[8][10] * (F[5][9] * D[9][10] + F[5][13] * D[10][13] + F[5][14] * D[10][14] + F[5][15] * D[10][15] + F[5][6] * D[6][10] + F[5][7] * D[7][10] + F[5][8] * D[8][10]) + F[8][11] * (F[5][9] * D[9][11] + F[5][13] * D[11][13] + F[5][14] * D[11][14] + F[5][15] * D[11][15] + F[5][6] * D[6][11] + F[5][7] * D[7][11] + F[5][8] * D[8][11]) + F[8][12] * (F[5][9] * D[9][12] + F[5][13] * D[12][13] + F[5][14] * D[12][14] + F[5][15] * D[12][15] + F[5][6] * D[6][12] + F[5][7] * D[7][12] + F[5][8] * D[8][12]) + F[8][6] * (F[5][6] * D[6][6] + F[5][7] * D[6][7] + F[5][8] * D[6][8] + F[5][9] * D[6][9] + F[5][13] * D[6][13] + F[5][14] * D[6][14] + F[5][15] * D[6][15]) + F[8][7] * (F[5][6] * D[6][7] + F[5][7] * D[7][7] + F[5][8] * D[7][8] + F[5][9] * D[7][9] + F[5][13] * D[7][13] + F[5][14] * D[7][14] + F[5][15] * D[7][15])) * Tsq + (F[5][6] * D[6][8] + F[5][7] * D[7][8] + F[8][6] * D[5][6] + F[8][7] * D[5][7] + F[5][8] * D[8][8] + F[5][9] * D[8][9] + F[8][9] * D[5][9] + F[8][10] * D[5][10] + F[8][11] * D[5][11] + F[8][12] * D[5][12] + F[5][13] * D[8][13] + F[5][14] * D[8][14] + F[5][15] * D[8][15]) * T + D[5][8];
491 P[5][9] = P[9][5] = (F[9][10] * (F[5][9] * D[9][10] + F[5][13] * D[10][13] + F[5][14] * D[10][14] + F[5][15] * D[10][15] + F[5][6] * D[6][10] + F[5][7] * D[7][10] + F[5][8] * D[8][10]) + F[9][11] * (F[5][9] * D[9][11] + F[5][13] * D[11][13] + F[5][14] * D[11][14] + F[5][15] * D[11][15] + F[5][6] * D[6][11] + F[5][7] * D[7][11] + F[5][8] * D[8][11]) + F[9][12] * (F[5][9] * D[9][12] + F[5][13] * D[12][13] + F[5][14] * D[12][14] + F[5][15] * D[12][15] + F[5][6] * D[6][12] + F[5][7] * D[7][12] + F[5][8] * D[8][12]) + F[9][6] * (F[5][6] * D[6][6] + F[5][7] * D[6][7] + F[5][8] * D[6][8] + F[5][9] * D[6][9] + F[5][13] * D[6][13] + F[5][14] * D[6][14] + F[5][15] * D[6][15]) + F[9][7] * (F[5][6] * D[6][7] + F[5][7] * D[7][7] + F[5][8] * D[7][8] + F[5][9] * D[7][9] + F[5][13] * D[7][13] + F[5][14] * D[7][14] + F[5][15] * D[7][15]) + F[9][8] * (F[5][6] * D[6][8] + F[5][7] * D[7][8] + F[5][8] * D[8][8] + F[5][9] * D[8][9] + F[5][13] * D[8][13] + F[5][14] * D[8][14] + F[5][15] * D[8][15])) * Tsq + (F[9][6] * D[5][6] + F[9][7] * D[5][7] + F[9][8] * D[5][8] + F[5][9] * D[9][9] + F[9][10] * D[5][10] + F[9][11] * D[5][11] + F[9][12] * D[5][12] + F[5][13] * D[9][13] + F[5][14] * D[9][14] + F[5][15] * D[9][15] + F[5][6] * D[6][9] + F[5][7] * D[7][9] + F[5][8] * D[8][9]) * T + D[5][9];
492 P[5][10] = P[10][5] = (F[5][9] * D[9][10] + F[5][13] * D[10][13] + F[5][14] * D[10][14] + F[5][15] * D[10][15] + F[5][6] * D[6][10] + F[5][7] * D[7][10] + F[5][8] * D[8][10]) * T + D[5][10];
493 P[5][11] = P[11][5] = (F[5][9] * D[9][11] + F[5][13] * D[11][13] + F[5][14] * D[11][14] + F[5][15] * D[11][15] + F[5][6] * D[6][11] + F[5][7] * D[7][11] + F[5][8] * D[8][11]) * T + D[5][11];
494 P[5][12] = P[12][5] = (F[5][9] * D[9][12] + F[5][13] * D[12][13] + F[5][14] * D[12][14] + F[5][15] * D[12][15] + F[5][6] * D[6][12] + F[5][7] * D[7][12] + F[5][8] * D[8][12]) * T + D[5][12];
495 P[5][13] = P[13][5] = (F[5][9] * D[9][13] + F[5][13] * D[13][13] + F[5][14] * D[13][14] + F[5][15] * D[13][15] + F[5][6] * D[6][13] + F[5][7] * D[7][13] + F[5][8] * D[8][13]) * T + D[5][13];
496 P[5][14] = P[14][5] = (F[5][9] * D[9][14] + F[5][13] * D[13][14] + F[5][14] * D[14][14] + F[5][15] * D[14][15] + F[5][6] * D[6][14] + F[5][7] * D[7][14] + F[5][8] * D[8][14]) * T + D[5][14];
497 P[5][15] = P[15][5] = (F[5][9] * D[9][15] + F[5][13] * D[13][15] + F[5][14] * D[14][15] + F[5][15] * D[14][15] + F[5][6] * D[6][15] + F[5][7] * D[7][15] + F[5][8] * D[8][15]) * T + D[5][15];
498 P[6][6] = (Q[0] * G[6][0] * G[6][0] + Q[1] * G[6][1] * G[6][1] + Q[2] * G[6][2] * G[6][2] + F[6][9] * (F[6][9] * D[9][9] + F[6][10] * D[9][10] + F[6][11] * D[9][11] + F[6][12] * D[9][12] + F[6][7] * D[7][9] + F[6][8] * D[8][9]) + F[6][10] * (F[6][9] * D[9][10] + F[6][10] * D[10][10] + F[6][11] * D[10][11] + F[6][12] * D[10][12] + F[6][7] * D[7][10] + F[6][8] * D[8][10]) + F[6][11] * (F[6][9] * D[9][11] + F[6][10] * D[10][11] + F[6][11] * D[11][11] + F[6][12] * D[11][12] + F[6][7] * D[7][11] + F[6][8] * D[8][11]) + F[6][12] * (F[6][9] * D[9][12] + F[6][10] * D[10][12] + F[6][11] * D[11][12] + F[6][12] * D[12][12] + F[6][7] * D[7][12] + F[6][8] * D[8][12]) + F[6][7] * (F[6][7] * D[7][7] + F[6][8] * D[7][8] + F[6][9] * D[7][9] + F[6][10] * D[7][10] + F[6][11] * D[7][11] + F[6][12] * D[7][12]) + F[6][8] * (F[6][7] * D[7][8] + F[6][8] * D[8][8] + F[6][9] * D[8][9] + F[6][10] * D[8][10] + F[6][11] * D[8][11] + F[6][12] * D[8][12])) * Tsq + (2 * F[6][7] * D[6][7] + 2 * F[6][8] * D[6][8] + 2 * F[6][9] * D[6][9] + 2 * F[6][10] * D[6][10] + 2 * F[6][11] * D[6][11] + 2 * F[6][12] * D[6][12]) * T + D[6][6];
499 P[6][7] = P[7][6] = (F[7][9] * (F[6][9] * D[9][9] + F[6][10] * D[9][10] + F[6][11] * D[9][11] + F[6][12] * D[9][12] + F[6][7] * D[7][9] + F[6][8] * D[8][9]) + F[7][10] * (F[6][9] * D[9][10] + F[6][10] * D[10][10] + F[6][11] * D[10][11] + F[6][12] * D[10][12] + F[6][7] * D[7][10] + F[6][8] * D[8][10]) + F[7][11] * (F[6][9] * D[9][11] + F[6][10] * D[10][11] + F[6][11] * D[11][11] + F[6][12] * D[11][12] + F[6][7] * D[7][11] + F[6][8] * D[8][11]) + F[7][12] * (F[6][9] * D[9][12] + F[6][10] * D[10][12] + F[6][11] * D[11][12] + F[6][12] * D[12][12] + F[6][7] * D[7][12] + F[6][8] * D[8][12]) + F[7][6] * (F[6][7] * D[6][7] + F[6][8] * D[6][8] + F[6][9] * D[6][9] + F[6][10] * D[6][10] + F[6][11] * D[6][11] + F[6][12] * D[6][12]) + F[7][8] * (F[6][7] * D[7][8] + F[6][8] * D[8][8] + F[6][9] * D[8][9] + F[6][10] * D[8][10] + F[6][11] * D[8][11] + F[6][12] * D[8][12]) + G[6][0] * G[7][0] * Q[0] + G[6][1] * G[7][1] * Q[1] + G[6][2] * G[7][2] * Q[2]) * Tsq + (F[7][6] * D[6][6] + F[6][7] * D[7][7] + F[6][8] * D[7][8] + F[7][8] * D[6][8] + F[6][9] * D[7][9] + F[7][9] * D[6][9] + F[6][10] * D[7][10] + F[7][10] * D[6][10] + F[6][11] * D[7][11] + F[7][11] * D[6][11] + F[6][12] * D[7][12] + F[7][12] * D[6][12]) * T + D[6][7];
500 P[6][8] = P[8][6] = (F[8][9] * (F[6][9] * D[9][9] + F[6][10] * D[9][10] + F[6][11] * D[9][11] + F[6][12] * D[9][12] + F[6][7] * D[7][9] + F[6][8] * D[8][9]) + F[8][10] * (F[6][9] * D[9][10] + F[6][10] * D[10][10] + F[6][11] * D[10][11] + F[6][12] * D[10][12] + F[6][7] * D[7][10] + F[6][8] * D[8][10]) + F[8][11] * (F[6][9] * D[9][11] + F[6][10] * D[10][11] + F[6][11] * D[11][11] + F[6][12] * D[11][12] + F[6][7] * D[7][11] + F[6][8] * D[8][11]) + F[8][12] * (F[6][9] * D[9][12] + F[6][10] * D[10][12] + F[6][11] * D[11][12] + F[6][12] * D[12][12] + F[6][7] * D[7][12] + F[6][8] * D[8][12]) + F[8][6] * (F[6][7] * D[6][7] + F[6][8] * D[6][8] + F[6][9] * D[6][9] + F[6][10] * D[6][10] + F[6][11] * D[6][11] + F[6][12] * D[6][12]) + F[8][7] * (F[6][7] * D[7][7] + F[6][8] * D[7][8] + F[6][9] * D[7][9] + F[6][10] * D[7][10] + F[6][11] * D[7][11] + F[6][12] * D[7][12]) + G[6][0] * G[8][0] * Q[0] + G[6][1] * G[8][1] * Q[1] + G[6][2] * G[8][2] * Q[2]) * Tsq + (F[6][7] * D[7][8] + F[8][6] * D[6][6] + F[8][7] * D[6][7] + F[6][8] * D[8][8] + F[6][9] * D[8][9] + F[8][9] * D[6][9] + F[6][10] * D[8][10] + F[8][10] * D[6][10] + F[6][11] * D[8][11] + F[8][11] * D[6][11] + F[6][12] * D[8][12] + F[8][12] * D[6][12]) * T + D[6][8];
501 P[6][9] = P[9][6] = (F[9][10] * (F[6][9] * D[9][10] + F[6][10] * D[10][10] + F[6][11] * D[10][11] + F[6][12] * D[10][12] + F[6][7] * D[7][10] + F[6][8] * D[8][10]) + F[9][11] * (F[6][9] * D[9][11] + F[6][10] * D[10][11] + F[6][11] * D[11][11] + F[6][12] * D[11][12] + F[6][7] * D[7][11] + F[6][8] * D[8][11]) + F[9][12] * (F[6][9] * D[9][12] + F[6][10] * D[10][12] + F[6][11] * D[11][12] + F[6][12] * D[12][12] + F[6][7] * D[7][12] + F[6][8] * D[8][12]) + F[9][6] * (F[6][7] * D[6][7] + F[6][8] * D[6][8] + F[6][9] * D[6][9] + F[6][10] * D[6][10] + F[6][11] * D[6][11] + F[6][12] * D[6][12]) + F[9][7] * (F[6][7] * D[7][7] + F[6][8] * D[7][8] + F[6][9] * D[7][9] + F[6][10] * D[7][10] + F[6][11] * D[7][11] + F[6][12] * D[7][12]) + F[9][8] * (F[6][7] * D[7][8] + F[6][8] * D[8][8] + F[6][9] * D[8][9] + F[6][10] * D[8][10] + F[6][11] * D[8][11] + F[6][12] * D[8][12]) + G[9][0] * G[6][0] * Q[0] + G[9][1] * G[6][1] * Q[1] + G[9][2] * G[6][2] * Q[2]) * Tsq + (F[9][6] * D[6][6] + F[9][7] * D[6][7] + F[9][8] * D[6][8] + F[6][9] * D[9][9] + F[9][10] * D[6][10] + F[6][10] * D[9][10] + F[9][11] * D[6][11] + F[6][11] * D[9][11] + F[9][12] * D[6][12] + F[6][12] * D[9][12] + F[6][7] * D[7][9] + F[6][8] * D[8][9]) * T + D[6][9];
502 P[6][10] = P[10][6] = (F[6][9] * D[9][10] + F[6][10] * D[10][10] + F[6][11] * D[10][11] + F[6][12] * D[10][12] + F[6][7] * D[7][10] + F[6][8] * D[8][10]) * T + D[6][10];
503 P[6][11] = P[11][6] = (F[6][9] * D[9][11] + F[6][10] * D[10][11] + F[6][11] * D[11][11] + F[6][12] * D[11][12] + F[6][7] * D[7][11] + F[6][8] * D[8][11]) * T + D[6][11];
504 P[6][12] = P[12][6] = (F[6][9] * D[9][12] + F[6][10] * D[10][12] + F[6][11] * D[11][12] + F[6][12] * D[12][12] + F[6][7] * D[7][12] + F[6][8] * D[8][12]) * T + D[6][12];
505 P[6][13] = P[13][6] = (F[6][9] * D[9][13] + F[6][10] * D[10][13] + F[6][11] * D[11][13] + F[6][12] * D[12][13] + F[6][7] * D[7][13] + F[6][8] * D[8][13]) * T + D[6][13];
506 P[6][14] = P[14][6] = (F[6][9] * D[9][14] + F[6][10] * D[10][14] + F[6][11] * D[11][14] + F[6][12] * D[12][14] + F[6][7] * D[7][14] + F[6][8] * D[8][14]) * T + D[6][14];
507 P[6][15] = P[15][6] = (F[6][9] * D[9][15] + F[6][10] * D[10][15] + F[6][11] * D[11][15] + F[6][12] * D[12][15] + F[6][7] * D[7][15] + F[6][8] * D[8][15]) * T + D[6][15];
508 P[7][7] = (Q[0] * G[7][0] * G[7][0] + Q[1] * G[7][1] * G[7][1] + Q[2] * G[7][2] * G[7][2] + F[7][9] * (F[7][9] * D[9][9] + F[7][10] * D[9][10] + F[7][11] * D[9][11] + F[7][12] * D[9][12] + F[7][6] * D[6][9] + F[7][8] * D[8][9]) + F[7][10] * (F[7][9] * D[9][10] + F[7][10] * D[10][10] + F[7][11] * D[10][11] + F[7][12] * D[10][12] + F[7][6] * D[6][10] + F[7][8] * D[8][10]) + F[7][11] * (F[7][9] * D[9][11] + F[7][10] * D[10][11] + F[7][11] * D[11][11] + F[7][12] * D[11][12] + F[7][6] * D[6][11] + F[7][8] * D[8][11]) + F[7][12] * (F[7][9] * D[9][12] + F[7][10] * D[10][12] + F[7][11] * D[11][12] + F[7][12] * D[12][12] + F[7][6] * D[6][12] + F[7][8] * D[8][12]) + F[7][6] * (F[7][6] * D[6][6] + F[7][8] * D[6][8] + F[7][9] * D[6][9] + F[7][10] * D[6][10] + F[7][11] * D[6][11] + F[7][12] * D[6][12]) + F[7][8] * (F[7][6] * D[6][8] + F[7][8] * D[8][8] + F[7][9] * D[8][9] + F[7][10] * D[8][10] + F[7][11] * D[8][11] + F[7][12] * D[8][12])) * Tsq + (2 * F[7][6] * D[6][7] + 2 * F[7][8] * D[7][8] + 2 * F[7][9] * D[7][9] + 2 * F[7][10] * D[7][10] + 2 * F[7][11] * D[7][11] + 2 * F[7][12] * D[7][12]) * T + D[7][7];
509 P[7][8] = P[8][7] = (F[8][9] * (F[7][9] * D[9][9] + F[7][10] * D[9][10] + F[7][11] * D[9][11] + F[7][12] * D[9][12] + F[7][6] * D[6][9] + F[7][8] * D[8][9]) + F[8][10] * (F[7][9] * D[9][10] + F[7][10] * D[10][10] + F[7][11] * D[10][11] + F[7][12] * D[10][12] + F[7][6] * D[6][10] + F[7][8] * D[8][10]) + F[8][11] * (F[7][9] * D[9][11] + F[7][10] * D[10][11] + F[7][11] * D[11][11] + F[7][12] * D[11][12] + F[7][6] * D[6][11] + F[7][8] * D[8][11]) + F[8][12] * (F[7][9] * D[9][12] + F[7][10] * D[10][12] + F[7][11] * D[11][12] + F[7][12] * D[12][12] + F[7][6] * D[6][12] + F[7][8] * D[8][12]) + F[8][6] * (F[7][6] * D[6][6] + F[7][8] * D[6][8] + F[7][9] * D[6][9] + F[7][10] * D[6][10] + F[7][11] * D[6][11] + F[7][12] * D[6][12]) + F[8][7] * (F[7][6] * D[6][7] + F[7][8] * D[7][8] + F[7][9] * D[7][9] + F[7][10] * D[7][10] + F[7][11] * D[7][11] + F[7][12] * D[7][12]) + G[7][0] * G[8][0] * Q[0] + G[7][1] * G[8][1] * Q[1] + G[7][2] * G[8][2] * Q[2]) * Tsq + (F[7][6] * D[6][8] + F[8][6] * D[6][7] + F[8][7] * D[7][7] + F[7][8] * D[8][8] + F[7][9] * D[8][9] + F[8][9] * D[7][9] + F[7][10] * D[8][10] + F[8][10] * D[7][10] + F[7][11] * D[8][11] + F[8][11] * D[7][11] + F[7][12] * D[8][12] + F[8][12] * D[7][12]) * T + D[7][8];
510 P[7][9] = P[9][7] = (F[9][10] * (F[7][9] * D[9][10] + F[7][10] * D[10][10] + F[7][11] * D[10][11] + F[7][12] * D[10][12] + F[7][6] * D[6][10] + F[7][8] * D[8][10]) + F[9][11] * (F[7][9] * D[9][11] + F[7][10] * D[10][11] + F[7][11] * D[11][11] + F[7][12] * D[11][12] + F[7][6] * D[6][11] + F[7][8] * D[8][11]) + F[9][12] * (F[7][9] * D[9][12] + F[7][10] * D[10][12] + F[7][11] * D[11][12] + F[7][12] * D[12][12] + F[7][6] * D[6][12] + F[7][8] * D[8][12]) + F[9][6] * (F[7][6] * D[6][6] + F[7][8] * D[6][8] + F[7][9] * D[6][9] + F[7][10] * D[6][10] + F[7][11] * D[6][11] + F[7][12] * D[6][12]) + F[9][7] * (F[7][6] * D[6][7] + F[7][8] * D[7][8] + F[7][9] * D[7][9] + F[7][10] * D[7][10] + F[7][11] * D[7][11] + F[7][12] * D[7][12]) + F[9][8] * (F[7][6] * D[6][8] + F[7][8] * D[8][8] + F[7][9] * D[8][9] + F[7][10] * D[8][10] + F[7][11] * D[8][11] + F[7][12] * D[8][12]) + G[9][0] * G[7][0] * Q[0] + G[9][1] * G[7][1] * Q[1] + G[9][2] * G[7][2] * Q[2]) * Tsq + (F[9][6] * D[6][7] + F[9][7] * D[7][7] + F[9][8] * D[7][8] + F[7][9] * D[9][9] + F[9][10] * D[7][10] + F[7][10] * D[9][10] + F[9][11] * D[7][11] + F[7][11] * D[9][11] + F[9][12] * D[7][12] + F[7][12] * D[9][12] + F[7][6] * D[6][9] + F[7][8] * D[8][9]) * T + D[7][9];
511 P[7][10] = P[10][7] = (F[7][9] * D[9][10] + F[7][10] * D[10][10] + F[7][11] * D[10][11] + F[7][12] * D[10][12] + F[7][6] * D[6][10] + F[7][8] * D[8][10]) * T + D[7][10];
512 P[7][11] = P[11][7] = (F[7][9] * D[9][11] + F[7][10] * D[10][11] + F[7][11] * D[11][11] + F[7][12] * D[11][12] + F[7][6] * D[6][11] + F[7][8] * D[8][11]) * T + D[7][11];
513 P[7][12] = P[12][7] = (F[7][9] * D[9][12] + F[7][10] * D[10][12] + F[7][11] * D[11][12] + F[7][12] * D[12][12] + F[7][6] * D[6][12] + F[7][8] * D[8][12]) * T + D[7][12];
514 P[7][13] = P[13][7] = (F[7][9] * D[9][13] + F[7][10] * D[10][13] + F[7][11] * D[11][13] + F[7][12] * D[12][13] + F[7][6] * D[6][13] + F[7][8] * D[8][13]) * T + D[7][13];
515 P[7][14] = P[14][7] = (F[7][9] * D[9][14] + F[7][10] * D[10][14] + F[7][11] * D[11][14] + F[7][12] * D[12][14] + F[7][6] * D[6][14] + F[7][8] * D[8][14]) * T + D[7][14];
516 P[7][15] = P[15][7] = (F[7][9] * D[9][15] + F[7][10] * D[10][15] + F[7][11] * D[11][15] + F[7][12] * D[12][15] + F[7][6] * D[6][15] + F[7][8] * D[8][15]) * T + D[7][15];
517 P[8][8] = (Q[0] * G[8][0] * G[8][0] + Q[1] * G[8][1] * G[8][1] + Q[2] * G[8][2] * G[8][2] + F[8][9] * (F[8][9] * D[9][9] + F[8][10] * D[9][10] + F[8][11] * D[9][11] + F[8][12] * D[9][12] + F[8][6] * D[6][9] + F[8][7] * D[7][9]) + F[8][10] * (F[8][9] * D[9][10] + F[8][10] * D[10][10] + F[8][11] * D[10][11] + F[8][12] * D[10][12] + F[8][6] * D[6][10] + F[8][7] * D[7][10]) + F[8][11] * (F[8][9] * D[9][11] + F[8][10] * D[10][11] + F[8][11] * D[11][11] + F[8][12] * D[11][12] + F[8][6] * D[6][11] + F[8][7] * D[7][11]) + F[8][12] * (F[8][9] * D[9][12] + F[8][10] * D[10][12] + F[8][11] * D[11][12] + F[8][12] * D[12][12] + F[8][6] * D[6][12] + F[8][7] * D[7][12]) + F[8][6] * (F[8][6] * D[6][6] + F[8][7] * D[6][7] + F[8][9] * D[6][9] + F[8][10] * D[6][10] + F[8][11] * D[6][11] + F[8][12] * D[6][12]) + F[8][7] * (F[8][6] * D[6][7] + F[8][7] * D[7][7] + F[8][9] * D[7][9] + F[8][10] * D[7][10] + F[8][11] * D[7][11] + F[8][12] * D[7][12])) * Tsq + (2 * F[8][6] * D[6][8] + 2 * F[8][7] * D[7][8] + 2 * F[8][9] * D[8][9] + 2 * F[8][10] * D[8][10] + 2 * F[8][11] * D[8][11] + 2 * F[8][12] * D[8][12]) * T + D[8][8];
518 P[8][9] = P[9][8] = (F[9][10] * (F[8][9] * D[9][10] + F[8][10] * D[10][10] + F[8][11] * D[10][11] + F[8][12] * D[10][12] + F[8][6] * D[6][10] + F[8][7] * D[7][10]) + F[9][11] * (F[8][9] * D[9][11] + F[8][10] * D[10][11] + F[8][11] * D[11][11] + F[8][12] * D[11][12] + F[8][6] * D[6][11] + F[8][7] * D[7][11]) + F[9][12] * (F[8][9] * D[9][12] + F[8][10] * D[10][12] + F[8][11] * D[11][12] + F[8][12] * D[12][12] + F[8][6] * D[6][12] + F[8][7] * D[7][12]) + F[9][6] * (F[8][6] * D[6][6] + F[8][7] * D[6][7] + F[8][9] * D[6][9] + F[8][10] * D[6][10] + F[8][11] * D[6][11] + F[8][12] * D[6][12]) + F[9][7] * (F[8][6] * D[6][7] + F[8][7] * D[7][7] + F[8][9] * D[7][9] + F[8][10] * D[7][10] + F[8][11] * D[7][11] + F[8][12] * D[7][12]) + F[9][8] * (F[8][6] * D[6][8] + F[8][7] * D[7][8] + F[8][9] * D[8][9] + F[8][10] * D[8][10] + F[8][11] * D[8][11] + F[8][12] * D[8][12]) + G[9][0] * G[8][0] * Q[0] + G[9][1] * G[8][1] * Q[1] + G[9][2] * G[8][2] * Q[2]) * Tsq + (F[9][6] * D[6][8] + F[9][7] * D[7][8] + F[9][8] * D[8][8] + F[8][9] * D[9][9] + F[9][10] * D[8][10] + F[8][10] * D[9][10] + F[9][11] * D[8][11] + F[8][11] * D[9][11] + F[9][12] * D[8][12] + F[8][12] * D[9][12] + F[8][6] * D[6][9] + F[8][7] * D[7][9]) * T + D[8][9];
519 P[8][10] = P[10][8] = (F[8][9] * D[9][10] + F[8][10] * D[10][10] + F[8][11] * D[10][11] + F[8][12] * D[10][12] + F[8][6] * D[6][10] + F[8][7] * D[7][10]) * T + D[8][10];
520 P[8][11] = P[11][8] = (F[8][9] * D[9][11] + F[8][10] * D[10][11] + F[8][11] * D[11][11] + F[8][12] * D[11][12] + F[8][6] * D[6][11] + F[8][7] * D[7][11]) * T + D[8][11];
521 P[8][12] = P[12][8] = (F[8][9] * D[9][12] + F[8][10] * D[10][12] + F[8][11] * D[11][12] + F[8][12] * D[12][12] + F[8][6] * D[6][12] + F[8][7] * D[7][12]) * T + D[8][12];
522 P[8][13] = P[13][8] = (F[8][9] * D[9][13] + F[8][10] * D[10][13] + F[8][11] * D[11][13] + F[8][12] * D[12][13] + F[8][6] * D[6][13] + F[8][7] * D[7][13]) * T + D[8][13];
523 P[8][14] = P[14][8] = (F[8][9] * D[9][14] + F[8][10] * D[10][14] + F[8][11] * D[11][14] + F[8][12] * D[12][14] + F[8][6] * D[6][14] + F[8][7] * D[7][14]) * T + D[8][14];
524 P[8][15] = P[15][8] = (F[8][9] * D[9][15] + F[8][10] * D[10][15] + F[8][11] * D[11][15] + F[8][12] * D[12][15] + F[8][6] * D[6][15] + F[8][7] * D[7][15]) * T + D[8][15];
525 P[9][9] = (Q[0] * G[9][0] * G[9][0] + Q[1] * G[9][1] * G[9][1] + Q[2] * G[9][2] * G[9][2] + F[9][10] * (F[9][10] * D[10][10] + F[9][11] * D[10][11] + F[9][12] * D[10][12] + F[9][6] * D[6][10] + F[9][7] * D[7][10] + F[9][8] * D[8][10]) + F[9][11] * (F[9][10] * D[10][11] + F[9][11] * D[11][11] + F[9][12] * D[11][12] + F[9][6] * D[6][11] + F[9][7] * D[7][11] + F[9][8] * D[8][11]) + F[9][12] * (F[9][10] * D[10][12] + F[9][11] * D[11][12] + F[9][12] * D[12][12] + F[9][6] * D[6][12] + F[9][7] * D[7][12] + F[9][8] * D[8][12]) + F[9][6] * (F[9][6] * D[6][6] + F[9][7] * D[6][7] + F[9][8] * D[6][8] + F[9][10] * D[6][10] + F[9][11] * D[6][11] + F[9][12] * D[6][12]) + F[9][7] * (F[9][6] * D[6][7] + F[9][7] * D[7][7] + F[9][8] * D[7][8] + F[9][10] * D[7][10] + F[9][11] * D[7][11] + F[9][12] * D[7][12]) + F[9][8] * (F[9][6] * D[6][8] + F[9][7] * D[7][8] + F[9][8] * D[8][8] + F[9][10] * D[8][10] + F[9][11] * D[8][11] + F[9][12] * D[8][12])) * Tsq + (2 * F[9][10] * D[9][10] + 2 * F[9][11] * D[9][11] + 2 * F[9][12] * D[9][12] + 2 * F[9][6] * D[6][9] + 2 * F[9][7] * D[7][9] + 2 * F[9][8] * D[8][9]) * T + D[9][9];
526 P[9][10] = P[10][9] = (F[9][10] * D[10][10] + F[9][11] * D[10][11] + F[9][12] * D[10][12] + F[9][6] * D[6][10] + F[9][7] * D[7][10] + F[9][8] * D[8][10]) * T + D[9][10];
527 P[9][11] = P[11][9] = (F[9][10] * D[10][11] + F[9][11] * D[11][11] + F[9][12] * D[11][12] + F[9][6] * D[6][11] + F[9][7] * D[7][11] + F[9][8] * D[8][11]) * T + D[9][11];
528 P[9][12] = P[12][9] = (F[9][10] * D[10][12] + F[9][11] * D[11][12] + F[9][12] * D[12][12] + F[9][6] * D[6][12] + F[9][7] * D[7][12] + F[9][8] * D[8][12]) * T + D[9][12];
529 P[9][13] = P[13][9] = (F[9][10] * D[10][13] + F[9][11] * D[11][13] + F[9][12] * D[12][13] + F[9][6] * D[6][13] + F[9][7] * D[7][13] + F[9][8] * D[8][13]) * T + D[9][13];
530 P[9][14] = P[14][9] = (F[9][10] * D[10][14] + F[9][11] * D[11][14] + F[9][12] * D[12][14] + F[9][6] * D[6][14] + F[9][7] * D[7][14] + F[9][8] * D[8][14]) * T + D[9][14];
531 P[9][15] = P[15][9] = (F[9][10] * D[10][15] + F[9][11] * D[11][15] + F[9][12] * D[12][15] + F[9][6] * D[6][15] + F[9][7] * D[7][15] + F[9][8] * D[8][15]) * T + D[9][15];
532 P[10][10] = Q[6] * Tsq + D[10][10];
533 P[10][11] = P[11][10] = D[10][11];
534 P[10][12] = P[12][10] = D[10][12];
535 P[10][13] = P[13][10] = D[10][13];
536 P[10][14] = P[14][10] = D[10][14];
537 P[10][15] = P[15][10] = D[10][15];
538 P[11][11] = Q[7] * Tsq + D[11][11];
539 P[11][12] = P[12][11] = D[11][12];
540 P[11][13] = P[13][11] = D[11][13];
541 P[11][14] = P[14][11] = D[11][14];
542 P[11][15] = P[15][11] = D[11][15];
543 P[12][12] = Q[8] * Tsq + D[12][12];
544 P[12][13] = P[13][12] = D[12][13];
545 P[12][14] = P[14][12] = D[12][14];
546 P[12][15] = P[15][12] = D[12][15];
547 P[13][13] = Q[9] * Tsq + D[13][13];
548 P[13][14] = P[14][13] = D[13][14];
549 P[13][15] = P[15][13] = D[13][15];
550 P[14][14] = Q[10] * Tsq + D[14][14];
551 P[14][15] = P[15][14] = D[14][15];
552 P[15][15] = Q[11] * Tsq + D[14][15];
554 #endif /* ifdef COVARIANCE_PREDICTION_GENERAL */
556 // ************* SerialUpdate *******************
557 // Does the update step of the Kalman filter for the covariance and estimate
558 // Outputs are Xnew & Pnew, and are written over P and X
559 // Z is actual measurement, Y is predicted measurement
560 // Xnew = X + K*(Z-Y), Pnew=(I-K*H)*P,
561 // where K=P*H'*inv[H*P*H'+R]
562 // NOTE the algorithm assumes R (measurement covariance matrix) is diagonal
563 // i.e. the measurment noises are uncorrelated.
564 // It therefore uses a serial update that requires no matrix inversion by
565 // processing the measurements one at a time.
566 // Algorithm - see Grewal and Andrews, "Kalman Filtering,2nd Ed" p.121 & p.253
567 // - or see Simon, "Optimal State Estimation," 1st Ed, p.150
568 // The SensorsUsed variable is a bitwise mask indicating which sensors
569 // should be used in the update.
570 // ************************************************
572 void SerialUpdate(float H[NUMV][NUMX], float R[NUMV], float Z[NUMV],
573 float Y[NUMV], float P[NUMX][NUMX], float X[NUMX],
574 uint16_t SensorsUsed)
576 float HP[NUMX], HPHR, Error;
577 uint8_t i, j, k, m;
579 for (m = 0; m < NUMV; m++) {
580 if (SensorsUsed & (0x01 << m)) { // use this sensor for update
581 for (j = 0; j < NUMX; j++) { // Find Hp = H*P
582 HP[j] = 0.0f;
583 for (k = 0; k < NUMX; k++) {
584 HP[j] += H[m][k] * P[k][j];
587 HPHR = R[m]; // Find HPHR = H*P*H' + R
588 for (k = 0; k < NUMX; k++) {
589 HPHR += HP[k] * H[m][k];
592 for (k = 0; k < NUMX; k++) {
593 K[k][m] = HP[k] / HPHR; // find K = HP/HPHR
595 for (i = 0; i < NUMX; i++) { // Find P(m)= P(m-1) + K*HP
596 for (j = i; j < NUMX; j++) {
597 P[i][j] = P[j][i] =
598 P[i][j] - K[i][m] * HP[j];
602 Error = Z[m] - Y[m];
603 for (i = 0; i < NUMX; i++) { // Find X(m)= X(m-1) + K*Error
604 X[i] = X[i] + K[i][m] * Error;
610 // ************* RungeKutta **********************
611 // Does a 4th order Runge Kutta numerical integration step
612 // Output, Xnew, is written over X
613 // NOTE the algorithm assumes time invariant state equations and
614 // constant inputs over integration step
615 // ************************************************
617 void RungeKutta(float X[NUMX], float U[NUMU], float dT)
619 float dT2 =
620 dT / 2.0f, K1[NUMX], K2[NUMX], K3[NUMX], K4[NUMX], Xlast[NUMX];
621 uint8_t i;
623 for (i = 0; i < NUMX; i++) {
624 Xlast[i] = X[i]; // make a working copy
626 StateEq(X, U, K1); // k1 = f(x,u)
627 for (i = 0; i < NUMX; i++) {
628 X[i] = Xlast[i] + dT2 * K1[i];
630 StateEq(X, U, K2); // k2 = f(x+0.5*dT*k1,u)
631 for (i = 0; i < NUMX; i++) {
632 X[i] = Xlast[i] + dT2 * K2[i];
634 StateEq(X, U, K3); // k3 = f(x+0.5*dT*k2,u)
635 for (i = 0; i < NUMX; i++) {
636 X[i] = Xlast[i] + dT * K3[i];
638 StateEq(X, U, K4); // k4 = f(x+dT*k3,u)
640 // Xnew = X + dT*(k1+2*k2+2*k3+k4)/6
641 for (i = 0; i < NUMX; i++) {
642 X[i] =
643 Xlast[i] + dT * (K1[i] + 2.0f * K2[i] + 2.0f * K3[i] +
644 K4[i]) / 6.0f;
648 // ************* Model Specific Stuff ***************************
649 // *** StateEq, MeasurementEq, LinerizeFG, and LinearizeH ********
651 // State Variables = [Pos Vel Quaternion GyroBias AccelBias]
652 // Deterministic Inputs = [AngularVel Accel]
653 // Disturbance Noise = [GyroNoise AccelNoise GyroRandomWalkNoise AccelRandomWalkNoise]
655 // Measurement Variables = [Pos Vel BodyFrameMagField Altimeter]
656 // Inputs to Measurement = [EarthFrameMagField]
658 // Notes: Pos and Vel in earth frame
659 // AngularVel and Accel in body frame
660 // MagFields are unit vectors
661 // Xdot is output of StateEq()
662 // F and G are outputs of LinearizeFG(), all elements not set should be zero
663 // y is output of OutputEq()
664 // H is output of LinearizeH(), all elements not set should be zero
665 // ************************************************
667 void StateEq(float X[NUMX], float U[NUMU], float Xdot[NUMX])
669 float ax, ay, az, wx, wy, wz, q0, q1, q2, q3;
671 ax = U[3] - X[13];
672 ay = U[4] - X[14];
673 az = U[5] - X[15]; // subtract the biases on accels
674 wx = U[0] - X[10];
675 wy = U[1] - X[11];
676 wz = U[2] - X[12]; // subtract the biases on gyros
677 q0 = X[6];
678 q1 = X[7];
679 q2 = X[8];
680 q3 = X[9];
682 // Pdot = V
683 Xdot[0] = X[3];
684 Xdot[1] = X[4];
685 Xdot[2] = X[5];
687 // Vdot = Reb*a
688 Xdot[3] =
689 (q0 * q0 + q1 * q1 - q2 * q2 - q3 * q3) * ax + 2.0f * (q1 * q2 -
690 q0 * q3) *
691 ay + 2.0f * (q1 * q3 + q0 * q2) * az;
692 Xdot[4] =
693 2.0f * (q1 * q2 + q0 * q3) * ax + (q0 * q0 - q1 * q1 + q2 * q2 -
694 q3 * q3) * ay + 2.0f * (q2 * q3 -
695 q0 * q1) *
697 Xdot[5] =
698 2.0f * (q1 * q3 - q0 * q2) * ax + 2.0f * (q2 * q3 + q0 * q1) * ay +
699 (q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3) * az + 9.81f;
701 // qdot = Q*w
702 Xdot[6] = (-q1 * wx - q2 * wy - q3 * wz) / 2.0f;
703 Xdot[7] = (q0 * wx - q3 * wy + q2 * wz) / 2.0f;
704 Xdot[8] = (q3 * wx + q0 * wy - q1 * wz) / 2.0f;
705 Xdot[9] = (-q2 * wx + q1 * wy + q0 * wz) / 2.0f;
707 // best guess is that bias stays constant
708 Xdot[10] = Xdot[11] = Xdot[12] = 0;
709 Xdot[13] = Xdot[14] = Xdot[15] = 0;
712 void LinearizeFG(float X[NUMX], float U[NUMU], float F[NUMX][NUMX],
713 float G[NUMX][NUMW])
715 float ax, ay, az, wx, wy, wz, q0, q1, q2, q3;
717 // ax=U[3]-X[13]; ay=U[4]-X[14]; az=U[5]-X[15]; // subtract the biases on accels
718 ax = U[3];
719 ay = U[4];
720 az = U[5]; // NO BIAS STATES ON ACCELS
721 wx = U[0] - X[10];
722 wy = U[1] - X[11];
723 wz = U[2] - X[12]; // subtract the biases on gyros
724 q0 = X[6];
725 q1 = X[7];
726 q2 = X[8];
727 q3 = X[9];
729 // Pdot = V
730 F[0][3] = F[1][4] = F[2][5] = 1.0f;
732 // dVdot/dq
733 F[3][6] = 2.0f * (q0 * ax - q3 * ay + q2 * az);
734 F[3][7] = 2.0f * (q1 * ax + q2 * ay + q3 * az);
735 F[3][8] = 2.0f * (-q2 * ax + q1 * ay + q0 * az);
736 F[3][9] = 2.0f * (-q3 * ax - q0 * ay + q1 * az);
737 F[4][6] = 2.0f * (q3 * ax + q0 * ay - q1 * az);
738 F[4][7] = 2.0f * (q2 * ax - q1 * ay - q0 * az);
739 F[4][8] = 2.0f * (q1 * ax + q2 * ay + q3 * az);
740 F[4][9] = 2.0f * (q0 * ax - q3 * ay + q2 * az);
741 F[5][6] = 2.0f * (-q2 * ax + q1 * ay + q0 * az);
742 F[5][7] = 2.0f * (q3 * ax + q0 * ay - q1 * az);
743 F[5][8] = 2.0f * (-q0 * ax + q3 * ay - q2 * az);
744 F[5][9] = 2.0f * (q1 * ax + q2 * ay + q3 * az);
746 // dVdot/dabias & dVdot/dna
747 F[3][13] = G[3][3] = -q0 * q0 - q1 * q1 + q2 * q2 + q3 * q3; F[3][14] = G[3][4] = 2.0f * (-q1 * q2 + q0 * q3); F[3][15] = G[3][5] = -2.0f * (q1 * q3 + q0 * q2);
748 F[4][13] = G[4][3] = -2.0f * (q1 * q2 + q0 * q3); F[4][14] = G[4][4] = -q0 * q0 + q1 * q1 - q2 * q2 + q3 * q3; F[4][15] = G[4][5] = 2.0f * (-q2 * q3 + q0 * q1);
749 F[5][13] = G[5][3] = 2.0f * (-q1 * q3 + q0 * q2); F[5][14] = G[5][4] = -2.0f * (q2 * q3 + q0 * q1); F[5][15] = G[5][5] = -q0 * q0 + q1 * q1 + q2 * q2 - q3 * q3;
751 // dqdot/dq
752 F[6][6] = 0;
753 F[6][7] = -wx / 2.0f;
754 F[6][8] = -wy / 2.0f;
755 F[6][9] = -wz / 2.0f;
756 F[7][6] = wx / 2.0f;
757 F[7][7] = 0;
758 F[7][8] = wz / 2.0f;
759 F[7][9] = -wy / 2.0f;
760 F[8][6] = wy / 2.0f;
761 F[8][7] = -wz / 2.0f;
762 F[8][8] = 0;
763 F[8][9] = wx / 2.0f;
764 F[9][6] = wz / 2.0f;
765 F[9][7] = wy / 2.0f;
766 F[9][8] = -wx / 2.0f;
767 F[9][9] = 0;
769 // dqdot/dwbias
770 F[6][10] = q1 / 2.0f;
771 F[6][11] = q2 / 2.0f;
772 F[6][12] = q3 / 2.0f;
773 F[7][10] = -q0 / 2.0f;
774 F[7][11] = q3 / 2.0f;
775 F[7][12] = -q2 / 2.0f;
776 F[8][10] = -q3 / 2.0f;
777 F[8][11] = -q0 / 2.0f;
778 F[8][12] = q1 / 2.0f;
779 F[9][10] = q2 / 2.0f;
780 F[9][11] = -q1 / 2.0f;
781 F[9][12] = -q0 / 2.0f;
783 // dVdot/dna - WITH BIAS STATES ON ACCELS - THIS DONE ABOVE
784 // G[3][3]=-q0*q0-q1*q1+q2*q2+q3*q3; G[3][4]=2*(-q1*q2+q0*q3); G[3][5]=-2*(q1*q3+q0*q2);
785 // G[4][3]=-2*(q1*q2+q0*q3); G[4][4]=-q0*q0+q1*q1-q2*q2+q3*q3; G[4][5]=2*(-q2*q3+q0*q1);
786 // G[5][3]=2*(-q1*q3+q0*q2); G[5][4]=-2*(q2*q3+q0*q1); G[5][5]=-q0*q0+q1*q1+q2*q2-q3*q3;
788 // dqdot/dnw
789 G[6][0] = q1 / 2.0f;
790 G[6][1] = q2 / 2.0f;
791 G[6][2] = q3 / 2.0f;
792 G[7][0] = -q0 / 2.0f;
793 G[7][1] = q3 / 2.0f;
794 G[7][2] = -q2 / 2.0f;
795 G[8][0] = -q3 / 2.0f;
796 G[8][1] = -q0 / 2.0f;
797 G[8][2] = q1 / 2.0f;
798 G[9][0] = q2 / 2.0f;
799 G[9][1] = -q1 / 2.0f;
800 G[9][2] = -q0 / 2.0f;
802 // dwbias = random walk noise
803 G[10][6] = G[11][7] = G[12][8] = 1.0f;
804 // dabias = random walk noise
805 G[13][9] = G[14][10] = G[15][11] = 1.0f;
808 void MeasurementEq(float X[NUMX], float Be[3], float Y[NUMV])
810 float q0, q1, q2, q3;
812 q0 = X[6];
813 q1 = X[7];
814 q2 = X[8];
815 q3 = X[9];
817 // first six outputs are P and V
818 Y[0] = X[0];
819 Y[1] = X[1];
820 Y[2] = X[2];
821 Y[3] = X[3];
822 Y[4] = X[4];
823 Y[5] = X[5];
825 // Bb=Rbe*Be
826 Y[6] =
827 (q0 * q0 + q1 * q1 - q2 * q2 - q3 * q3) * Be[0] +
828 2.0f * (q1 * q2 + q0 * q3) * Be[1] + 2.0f * (q1 * q3 -
829 q0 * q2) * Be[2];
830 Y[7] =
831 2.0f * (q1 * q2 - q0 * q3) * Be[0] + (q0 * q0 - q1 * q1 +
832 q2 * q2 - q3 * q3) * Be[1] +
833 2.0f * (q2 * q3 + q0 * q1) * Be[2];
834 Y[8] =
835 2.0f * (q1 * q3 + q0 * q2) * Be[0] + 2.0f * (q2 * q3 -
836 q0 * q1) * Be[1] +
837 (q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3) * Be[2];
839 // Alt = -Pz
840 Y[9] = X[2] * -1.0f;
843 void LinearizeH(float X[NUMX], float Be[3], float H[NUMV][NUMX])
845 float q0, q1, q2, q3;
847 q0 = X[6];
848 q1 = X[7];
849 q2 = X[8];
850 q3 = X[9];
852 // dP/dP=I;
853 H[0][0] = H[1][1] = H[2][2] = 1.0f;
854 // dV/dV=I;
855 H[3][3] = H[4][4] = H[5][5] = 1.0f;
857 // dBb/dq
858 H[6][6] = 2.0f * (q0 * Be[0] + q3 * Be[1] - q2 * Be[2]);
859 H[6][7] = 2.0f * (q1 * Be[0] + q2 * Be[1] + q3 * Be[2]);
860 H[6][8] = 2.0f * (-q2 * Be[0] + q1 * Be[1] - q0 * Be[2]);
861 H[6][9] = 2.0f * (-q3 * Be[0] + q0 * Be[1] + q1 * Be[2]);
862 H[7][6] = 2.0f * (-q3 * Be[0] + q0 * Be[1] + q1 * Be[2]);
863 H[7][7] = 2.0f * (q2 * Be[0] - q1 * Be[1] + q0 * Be[2]);
864 H[7][8] = 2.0f * (q1 * Be[0] + q2 * Be[1] + q3 * Be[2]);
865 H[7][9] = 2.0f * (-q0 * Be[0] - q3 * Be[1] + q2 * Be[2]);
866 H[8][6] = 2.0f * (q2 * Be[0] - q1 * Be[1] + q0 * Be[2]);
867 H[8][7] = 2.0f * (q3 * Be[0] - q0 * Be[1] - q1 * Be[2]);
868 H[8][8] = 2.0f * (q0 * Be[0] + q3 * Be[1] - q2 * Be[2]);
869 H[8][9] = 2.0f * (q1 * Be[0] + q2 * Be[1] + q3 * Be[2]);
871 // dAlt/dPz = -1
872 H[9][2] = -1.0f;
876 * @}
877 * @}