diff --git a/Run_FeatureMatching.m b/Run_FeatureMatching.m new file mode 100644 index 0000000..08ac70b --- /dev/null +++ b/Run_FeatureMatching.m @@ -0,0 +1,31 @@ +% Type your dataset path +Path_to_result = './Results\Result_img'; + +addpath('./Utils_FeatureMatching'); + +% Run feature extraction & matching +main_feature_matching_analysis(strcat(Path_to_result,'\indoor_class_room1_340Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\indoor_class_room2_401Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\indoor_class_room3_320Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\indoor_class_room4_263Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\indoor_common_room1_177Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\indoor_common_room2_95Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\indoor_lounage1_200Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\indoor_meeting_room1_198Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\indoor_meeting_room3_213Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\indoor_meeting_room2_191Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\outdoor_bench1_6420Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\outdoor_bench2_5530Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\outdoor_bicycle1_14230Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\outdoor_bicycle2_2680Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\outdoor_car1_15310Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\outdoor_car2_5530Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\outdoor_car3_4080Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\outdoor_car4_5520Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\outdoor_car5_5290Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\outdoor_car6_4539Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\outdoor_car7_8490Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\outdoor_scene1_7380Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\outdoor_scene2_7710Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\outdoor_weed1_3350Lux')); +main_feature_matching_analysis(strcat(Path_to_result,'\outdoor_weed2_3010Lux')); \ No newline at end of file diff --git a/Run_MetricsEvaluation.m b/Run_MetricsEvaluation.m new file mode 100644 index 0000000..f8eec29 --- /dev/null +++ b/Run_MetricsEvaluation.m @@ -0,0 +1,85 @@ +% Type your dataset path +Path_to_datset = './DataSet_AE'; + +addpath('./Utils_metric'); + +% Run Metric Evaluator +Eval_Metric(strcat(Path_to_datset,'\indoor_class_room1_340Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\indoor_class_room2_401Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\indoor_class_room3_320Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\indoor_class_room4_263Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\indoor_common_room1_177Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\indoor_common_room2_95Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\indoor_lounage1_200Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\indoor_meeting_room1_198Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\indoor_meeting_room3_213Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\indoor_meeting_room2_191Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\outdoor_bench1_6420Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\outdoor_bench2_5530Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\outdoor_bicycle1_14230Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\outdoor_bicycle2_2680Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\outdoor_car1_15310Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\outdoor_car2_5530Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\outdoor_car3_4080Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\outdoor_car4_5520Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\outdoor_car5_5290Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\outdoor_car6_4539Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\outdoor_car7_8490Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\outdoor_scene1_7380Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\outdoor_scene2_7710Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\outdoor_weed1_3350Lux\left')); +Eval_Metric(strcat(Path_to_datset,'\outdoor_weed2_3010Lux\left')); + +% Run hyper paramter tester +% Test_HyperParam(strcat(Path_to_datset,'\indoor_class_room1_340Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\indoor_class_room2_401Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\indoor_class_room3_320Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\indoor_class_room4_263Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\indoor_common_room1_177Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\indoor_common_room2_95Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\indoor_lounage1_200Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\indoor_meeting_room1_198Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\indoor_meeting_room3_213Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\indoor_meeting_room2_191Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\outdoor_bench1_6420Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\outdoor_bench2_5530Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\outdoor_bicycle1_14230Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\outdoor_bicycle2_2680Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\outdoor_car1_15310Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\outdoor_car2_5530Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\outdoor_car3_4080Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\outdoor_car4_5520Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\outdoor_car5_5290Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\outdoor_car6_4539Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\outdoor_car7_8490Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\outdoor_scene1_7380Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\outdoor_scene2_7710Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\outdoor_weed1_3350Lux\left')); +% Test_HyperParam(strcat(Path_to_datset,'\outdoor_weed2_3010Lux\left')); + +% Extract result img +Extract_Result(strcat(Path_to_datset,'\indoor_class_room1_340Lux\left')); +Extract_Result(strcat(Path_to_datset,'\indoor_class_room2_401Lux\left')); +Extract_Result(strcat(Path_to_datset,'\indoor_class_room3_320Lux\left')); +Extract_Result(strcat(Path_to_datset,'\indoor_class_room4_263Lux\left')); +Extract_Result(strcat(Path_to_datset,'\indoor_common_room1_177Lux\left')); +Extract_Result(strcat(Path_to_datset,'\indoor_common_room2_95Lux\left')); +Extract_Result(strcat(Path_to_datset,'\indoor_lounage1_200Lux\left')); +Extract_Result(strcat(Path_to_datset,'\indoor_meeting_room1_198Lux\left')); +Extract_Result(strcat(Path_to_datset,'\indoor_meeting_room3_213Lux\left')); +Extract_Result(strcat(Path_to_datset,'\indoor_meeting_room2_191Lux\left')); +Extract_Result(strcat(Path_to_datset,'\outdoor_bench1_6420Lux\left')); +Extract_Result(strcat(Path_to_datset,'\outdoor_bench2_5530Lux\left')); +Extract_Result(strcat(Path_to_datset,'\outdoor_bicycle1_14230Lux\left')); +Extract_Result(strcat(Path_to_datset,'\outdoor_bicycle2_2680Lux\left')); +Extract_Result(strcat(Path_to_datset,'\outdoor_car1_15310Lux\left')); +Extract_Result(strcat(Path_to_datset,'\outdoor_car2_5530Lux\left')); +Extract_Result(strcat(Path_to_datset,'\outdoor_car3_4080Lux\left')); +Extract_Result(strcat(Path_to_datset,'\outdoor_car4_5520Lux\left')); +Extract_Result(strcat(Path_to_datset,'\outdoor_car5_5290Lux\left')); +Extract_Result(strcat(Path_to_datset,'\outdoor_car6_4539Lux\left')); +Extract_Result(strcat(Path_to_datset,'\outdoor_car7_8490Lux\left')); +Extract_Result(strcat(Path_to_datset,'\outdoor_scene1_7380Lux\left')); +Extract_Result(strcat(Path_to_datset,'\outdoor_scene2_7710Lux\left')); +Extract_Result(strcat(Path_to_datset,'\outdoor_weed1_3350Lux\left')); +Extract_Result(strcat(Path_to_datset,'\outdoor_weed2_3010Lux\left')); diff --git a/Run_NMbasedControl.m b/Run_NMbasedControl.m new file mode 100644 index 0000000..5040bdf --- /dev/null +++ b/Run_NMbasedControl.m @@ -0,0 +1,31 @@ +% Type your dataset path +Path_to_result = './Results\Result_Exp'; + +addpath('./Utils_control'); + +% Run Test +Test_nelder_mead_AE(strcat(Path_to_result,'\indoor_class_room1_340Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\indoor_class_room2_401Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\indoor_class_room3_320Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\indoor_class_room4_263Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\indoor_common_room1_177Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\indoor_common_room2_95Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\indoor_lounage1_200Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\indoor_meeting_room1_198Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\indoor_meeting_room3_213Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\indoor_meeting_room2_191Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\outdoor_bench1_6420Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\outdoor_bench2_5530Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\outdoor_bicycle1_14230Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\outdoor_bicycle2_2680Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\outdoor_car1_15310Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\outdoor_car2_5530Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\outdoor_car3_4080Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\outdoor_car4_5520Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\outdoor_car5_5290Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\outdoor_car6_4539Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\outdoor_car7_8490Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\outdoor_scene1_7380Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\outdoor_scene2_7710Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\outdoor_weed1_3350Lux\workspace_upsampled_result.mat')); +Test_nelder_mead_AE(strcat(Path_to_result,'\outdoor_weed2_3010Lux\workspace_upsampled_result.mat')); diff --git a/Utils_Control/FindClosestPoint.m b/Utils_Control/FindClosestPoint.m new file mode 100644 index 0000000..0de2684 --- /dev/null +++ b/Utils_Control/FindClosestPoint.m @@ -0,0 +1,86 @@ +function x_ = FindClosestPoint(x, Flag_dataset) +%% Camera Exposure Control for Robust Robot Vision with Noise-Aware Image Assessment Metric +% +% Ukcheol Shin, Jinsun Park, Gyumin Shim, Francois Rameau, and In So Kweon +% +% IROS 2019 +% +% Please feel free to contact if you have any problems. +% +% E-mail : Ukcheol Shin (shinwc159@gmail.com / shinwc159@kaist.ac.kr) +% Robotics and Computer Vision Lab., EE, +% KAIST, Republic of Korea +% +% Project Page : https://sites.google.com/view/noise-aware-exposure-control +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Name : +% FindClosestPoint.m +% +% Returns the nearest point to the input point based on the interval previously used to upsample the dataset. +% +% Modified: +% +% 04 December 2019 +% +% Author: +% +% Ukcheol Shin +% +% Parameters: +% +% Input : x - Input point +% : Flag_dataset - flag to select the setttings for each dataset +% +% output : x_ - The point closest to the input point present in the upsampled data set +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + if ( nargin == 1 ) + Flag_dataset = 1; + end + + if(Flag_dataset == 0) % Outdoor dataset + Interval_gain = 2; + Interval_expt = 150; + Limit_gain = 20; + Lower_limit_expt = 100; + Upper_limit_expt = 7450; + elseif(Flag_dataset == 1) % Indoor dataset + Interval_gain = 1; + Interval_expt = 3000; + Limit_gain = 24; + Lower_limit_expt = 4000; + Upper_limit_expt = 67000; + end + + Gain = x(1,1); + Expt = x(1,2); + + if(mod(Gain,Interval_gain) >= Interval_gain/2) + Gain = Gain - mod(Gain,Interval_gain) + Interval_gain; + elseif(mod(Gain,Interval_gain) < Interval_gain/2) + Gain = Gain - mod(Gain,Interval_gain); + end + + if(mod(Expt,Interval_expt) >= Interval_expt/2) + Expt = Expt - mod(Expt,Interval_expt) + Interval_expt + Lower_limit_expt; + elseif(mod(Expt,Interval_expt) < Interval_expt/2) + Expt = Expt - mod(Expt,Interval_expt) + Lower_limit_expt; + end + + if(Gain > Limit_gain) + Gain = Limit_gain; + elseif(Gain < 0) + Gain = 0; + end + + if(Expt > Upper_limit_expt) + Expt = Upper_limit_expt; + elseif(Expt < Lower_limit_expt) + Expt = Lower_limit_expt; + end + + x_ = zeros(1,2); + x_(1,1) = Gain; + x_(1,2) = Expt; +end diff --git a/Utils_Control/Metric_our.m b/Utils_Control/Metric_our.m new file mode 100644 index 0000000..8fe12be --- /dev/null +++ b/Utils_Control/Metric_our.m @@ -0,0 +1,91 @@ +function f = Metric_our ( x , Path_UpsampledData) +%% Camera Exposure Control for Robust Robot Vision with Noise-Aware Image Assessment Metric +% +% Ukcheol Shin, Jinsun Park, Gyumin Shim, Francois Rameau, and In So Kweon +% +% IROS 2019 +% +% Please feel free to contact if you have any problems. +% +% E-mail : Ukcheol Shin (shinwc159@gmail.com / shinwc159@kaist.ac.kr) +% Robotics and Computer Vision Lab., EE, +% KAIST, Republic of Korea +% +% Project Page : https://sites.google.com/view/noise-aware-exposure-control +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Name : +% Metric_our +% +% Returns a value based on the proposed image evaluation method for the input point, +% which value is returned based on the " _upsample.mat" generated by +% the previous "Metric_Evaluaotr.m" and "Data_Interpolation.m" . +% +% Modified: +% +% 04 December 2019 +% +% Author: +% +% Ukcheol Shin +% +% Parameters: +% +% Input : x - input point, the dimension of x is 2x1, +% we assume x(1) component is "gain", x(2) component is "exposure time". +% output : f_x - Evaluated value based on our metric +% with given input parameter (gain, exposure time) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + if ( length ( x ) ~= 2 ) + error ( 'Error: function expects a two dimensional input\n' ); + end + + % load upsampled dataset. + % In this code, we use pre-calculated datapoint and evaluated value of each dataset. + persistent Xq Yq Zq Interval_Up_Gain Interval_Up_ExpT result_txt; + if ( nargin == 2 ) + load(Path_UpsampledData,'Xq','Yq','Zq', 'interval_ExpT','interval_dB'); + Interval_Up_Gain = interval_dB; + Interval_Up_ExpT = interval_ExpT; + result_txt = strcat(Path_UpsampledData(1:regexp(Path_UpsampledData,'workspace')-1), 'Traj_ExpTGain.txt'); + fileID = fopen(result_txt,'w'); + fclose(fileID); + else + fileID = fopen(result_txt,'a'); + fprintf(fileID , '%4.5f %4.5f\n' , x(1) , x(2)); + fclose(fileID); + end + + Gain = x(1); + Expt = x(2); + + if(mod(Gain, Interval_Up_Gain) >= Interval_Up_Gain/2) + Approxi_Gain = Gain - mod(Gain, Interval_Up_Gain) + Interval_Up_Gain; + elseif(mod(Gain, Interval_Up_Gain) < Interval_Up_Gain/2) + Approxi_Gain = Gain - mod(Gain, Interval_Up_Gain); + end + + if(mod(Expt, Interval_Up_ExpT) >= Interval_Up_ExpT/2) + Approxi_Expt = Expt - mod(Expt, Interval_Up_ExpT) + Interval_Up_ExpT; + elseif(mod(Expt, Interval_Up_ExpT) < Interval_Up_ExpT/2) + Approxi_Expt = Expt - mod(Expt, Interval_Up_ExpT); + end + + Gain_index = find(abs(Xq(1,:) - Approxi_Gain) < 0.001); + ExpT_index = find(abs(Yq(:,1) - Approxi_Expt) < 0.001); + + f = -Zq(ExpT_index,Gain_index); + + % Exception handler for out of range or nonexistent values. + if(isnan(f)) + f = 10^10; % instead of using "inf", use some large number + elseif(isempty(f)) + f = 10^10; + end + + fprintf ( 1, ' %9.3f', Approxi_Gain ); + fprintf ( 1, ' %9.3f', Approxi_Expt ); + fprintf ( 1, ' %9.3e\n', f ); + + return +end diff --git a/Utils_Control/Test_nelder_mead_AE.m b/Utils_Control/Test_nelder_mead_AE.m new file mode 100644 index 0000000..0fac5e7 --- /dev/null +++ b/Utils_Control/Test_nelder_mead_AE.m @@ -0,0 +1,142 @@ +function Test_nelder_mead_AE (Path_UpsampledData) +%% Camera Exposure Control for Robust Robot Vision with Noise-Aware Image Assessment Metric +% +% Ukcheol Shin, Jinsun Park, Gyumin Shim, Francois Rameau, and In So Kweon +% +% IROS 2019 +% +% Please feel free to contact if you have any problems. +% +% E-mail : Ukcheol Shin (shinwc159@gmail.com / shinwc159@kaist.ac.kr) +% Robotics and Computer Vision Lab., EE, +% KAIST, Republic of Korea +% +% Project Page : https://sites.google.com/view/noise-aware-exposure-control +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Name : +% Run_NelderMead_ExposureControl.m +% +% Modified: +% +% 17 December 2019 +% +% Author: +% +% Ukcheol Shin +% +% Reference: +% +% We refer and modify the matlab code written by Jeff Borggaard +% "https://people.sc.fsu.edu/~jburkardt/m_src/nelder_mead/nelder_mead.html". +% the paper reference is follows : +% +% John Nelder, Roger Mead, +% A simplex method for function minimization, +% Computer Journal, +% Volume 7, Number 4, January 1965, pages 308-313. +% +% Parameters: +% +% Input : Path_UpsampledData - Path of upsampled dataset file, +% this dataset is generated by +% "Extract_Result.m" file +% output : None +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + close all; + + fprintf ( 1, '\n' ); + fprintf ( 1, 'AE_NELDER_MEAD_TEST:\n' ); + + % Load saved result mat file + load(Path_UpsampledData, 'path_name', 'dataset_flag'); + + n = 2; + Alpha = 1.7; % Alpha decides the initial simplex size + flag_draw = true; + Flag_Dataset = dataset_flag; % Flag to select the setting for dataset type. + + %% 1. Construct initial simplex + % Generate random initial point + if(Flag_Dataset == 0) % Outdoor dataset + Init_Points = zeros(3,2); + Init_Points(1,1) = 2*(randi(11)-1); + Init_Points(1,2) = 150*(randi(50)-1) + 100; + elseif(Flag_Dataset == 1) % Indoor dataset + Init_Points = zeros(3,2); + Init_Points(1,1) = 1*(randi(25)-1); + Init_Points(1,2) = 3000*(randi(22)-1) + 4000; + end + + % Read initial image based on random generated point + Str_Init_Img = strcat('Param-ISO-',int2str(Init_Points(1,1)), '-ExpT-',int2str(Init_Points(1,2)), '.jpg'); + Path_Init_Img = strcat(path_name,'\',Str_Init_Img); + Initial_image = imread(Path_Init_Img); + + % Decide exporing points based on a intensity of current captured image. + Intensity = mean2(rgb2gray(Initial_image)); + + if(Intensity >= 128) + h = -1/Alpha*(Intensity/255); + elseif(Intensity < 128) + h = Alpha*(1 - Intensity/255); + end + + Init_Points(2,:) = FindClosestPoint(Init_Points(1,:).*(1 + h*[1,0]), Flag_Dataset); + Init_Points(3,:) = FindClosestPoint(Init_Points(1,:).*(1 + h*[0,1]), Flag_Dataset); + fprintf(1,'Initial Param : Gain : %d, ExpT : %d\n', Init_Points(1,1), Init_Points(1,2) ); + fprintf(1,'Second Param : Gain : %d, ExpT : %d\n', Init_Points(2,1), Init_Points(2,2) ); + fprintf(1,'Third Param : Gain : %d, ExpT : %d\n', Init_Points(3,1), Init_Points(3,2) ); + + %% 2. Run Nelder-Mead based Exposure Control Algorithm + + fprintf ( 1, '\n' ); + fprintf ( 1, ' Initial data:\n' ); + fprintf ( 1, '\n' ); + + for j = 1 : n + fprintf ( 1, ' ---X(%d)---', j ); + end + fprintf ( 1, ' ---F(X)---\n' ); + fprintf ( 1, '\n' ); + Metric_our( zeros(1,2) , Path_UpsampledData); % initialize + + [ xopt, n_feval ] = nelder_mead_AE ( Init_Points, @Metric_our, flag_draw , Path_UpsampledData); + + fprintf ( 1, '\n' ); + fprintf ( 1, ' Computed optimum after %d evaluations:\n', n_feval ); + fprintf ( 1, '\n' ); + for j = 1 : n + fprintf ( 1, ' ---X(%d)---', j ); + end + fprintf ( 1, ' ---F(X)---\n' ); + fprintf ( 1, '\n' ); + for j = 1 : n + fprintf ( 1, ' %10f', xopt(j) ); + end + fprintf ( 1, ' %10e\n', Metric_our ( xopt) ); + + %% 3. Display the Gain & ExpT trajectory + Result = importdata(strcat(Path_UpsampledData(1:regexp(Path_UpsampledData,'workspace')-1), 'Traj_ExpTGain.txt')); + + Result = Result(4:end,:); + t = 1:length(Result); + GainResult = Result(:,1); + ExpTResult = Result(:,2); + + figure; + plot(t,GainResult,'LineWidth',2.5); + set(gca,'FontName', 'Times New Roman','FontSize',17); + xlabel('Step','fontsize',20, 'fontweight','bold'); ylabel('Gain','fontsize',20, 'fontweight','bold'); grid on; %title('Gain-step graph'); + tt = [1,5,15,25,35,45]; hold on; + plot(tt,GainResult(tt),'r*'); + + figure; + plot(t,ExpTResult,'LineWidth',2.5); + set(gca,'FontName', 'Times New Roman','FontSize',17); + xlabel('Step','fontsize',20, 'fontweight','bold'); ylabel('ExpT','fontsize',20, 'fontweight','bold'); grid on; %title('ExpT-step graph'); + tt = [1,5,15,25,35,45]; hold on; + plot(tt,ExpTResult(tt),'r*'); + +return +end diff --git a/Utils_Control/nelder_mead_AE.m b/Utils_Control/nelder_mead_AE.m new file mode 100644 index 0000000..4cc95ee --- /dev/null +++ b/Utils_Control/nelder_mead_AE.m @@ -0,0 +1,394 @@ +function [ x_opt, n_feval ] = nelder_mead_AE (x, function_handle, flag_draw, UpsampledDataResult) +%% Camera Exposure Control for Robust Robot Vision with Noise-Aware Image Assessment Metric +% +% Ukcheol Shin, Jinsun Park, Gyumin Shim, Francois Rameau, and In So Kweon +% +% IROS 2019 +% +% Please feel free to contact if you have any problems. +% +% E-mail : Ukcheol Shin (shinwc159@gmail.com / shinwc159@kaist.ac.kr) +% Robotics and Computer Vision Lab., EE, +% KAIST, Republic of Korea +% +% Project Page : https://sites.google.com/view/noise-aware-exposure-control +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% NELDER_MEAD performs the Nelder-Mead optimization search. +% Name : +% nelder_mead_AE.m +% +% Modified: +% +% 17 December 2019 +% +% Author: +% +% Ukcheol Shin +% +% Reference: +% +% We refer and modify the matlab code written by Jeff Borggaard +% "https://people.sc.fsu.edu/~jburkardt/m_src/nelder_mead/nelder_mead.html". +% the paper reference is follows : +% +% John Nelder, Roger Mead, +% A simplex method for function minimization, +% Computer Journal, +% Volume 7, Number 4, January 1965, pages 308-313. +% +% Parameters: +% +% Input, real X(M+1,M), contains a list of distinct points that serve as +% initial guesses for the solution. If the dimension of the space is M, +% then the matrix must contain exactly M+1 points. For instance, +% for a 2D space, you supply 3 points. Each row of the matrix contains +% one point; for a 2D space, this means that X would be a +% 3x2 matrix. +% +% Input, handle FUNCTION_HANDLE, a quoted expression for the function, +% or the name of an M-file that defines the function, preceded by an +% "@" sign; +% +% Input, logical FLAG_DRAW, an optional argument; if present, and set to 1, +% it will cause the program to display a graphical image of the contours +% and solution procedure. Note that this option only makes sense for +% problems in 2D, that is, with N=2. +% +% Input, string UpsampledData , a path of upsampled dataset file, +% this dataset is generated by "Extract_Result.m" file +% +% Output, real X_OPT, the optimal value of X found by the algorithm. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + %% 0. Define algorithm constants + rho = 1; % rho > 0, reflection coefficient + xi = 2; % xi > max(rho, 1), expansion coefficient + gam = 0.5; % 0 < gam < 1, contraction coefficient + sig = 0.5; % 0 < sig < 1, shrink coefficient + + tolerance = 1.0E-05; % end criteria + max_feval = 50; + + global Img_path; + global step; + global Flag_Dataset; + + load(UpsampledDataResult); + Flag_Dataset = dataset_flag; + Img_path = path_name; + step = 1; + + %% 1.Initialization + [ temp, n_dim ] = size ( x ); + + if ( temp ~= n_dim + 1 ) + fprintf ( 1, '\n' ); + fprintf ( 1, 'NELDER_MEAD - Fatal error!\n' ); + error(' Number of points must be = number of design variables + 1\n'); + end + + if ( flag_draw ) + xp = Xq(1,:); + yp = Yq(:,1)'; + fp = -Zq; % minimization + + % Find GT point + [~, idx] = max(Results_Our(:,3)); + GT_value = Results_Our(idx,:); + + figure (2) + subplot(1,2,1); + hold on; + contour(xp,yp,fp,50); + set(gca,'FontName', 'Times New Roman','FontSize',17); + xlabel('Gain','fontsize',20, 'fontweight','bold'); ylabel('ExpT','fontsize',20, 'fontweight','bold'); + set(gcf,'units','normalized','outerposition',[0.5 0.5 0.5 0.5]) + + % Draw starting & GT points + plot(x(1,1),x(1,2),'m*','MarkerSize',14,'linewidth',2.5); % ½ÃÀÛ°ª + plot(GT_value(1),GT_value(2),'g*','MarkerSize',14,'linewidth',2.5); % GT + + draw_image(x(1,:)); + draw_image(x(2,:)); + draw_image(x(3,:)); + + draw_simplex(x); + end + + % Evaluate each point of initial simplex + [f ] = evaluate ( x, function_handle ); + n_feval = n_dim + 1; + + [ f, index ] = sort ( f ); + x = x(index,:); + + % Begin the Nelder Mead iteration. + converged = 0; + diverged = 0; + + while ( ~converged && ~diverged ) + % 1. Compute the midpoint of the simplex opposite the worst point. + x_bar = sum ( x(1:n_dim,:) ) / n_dim; + + % 2. Compute the reflection point. + x_r = ( 1 + rho ) * x_bar - rho * x(n_dim+1,:); + f_r = feval(function_handle,x_r); + n_feval = n_feval + 1; + + if(flag_draw ==1) + draw_image(x_r); + end + + % 3-1. Accept the reflection point + if ( f(1) <= f_r && f_r <= f(n_dim) ) + x(n_dim+1,:) = x_r; + f(n_dim+1 ) = f_r; + + if (flag_draw) + figure(2); subplot(1,2,1); title('reflection', 'fontsize',18, 'fontweight','bold') + end + + % 3-2. Test for possible expansion. + elseif ( f_r < f(1) ) + x_e = ( 1 + rho * xi ) * x_bar - rho * xi * x(n_dim+1,:); + f_e = feval(function_handle,x_e); + n_feval = n_feval+1; + + if(flag_draw ==1) + draw_image(x_e); + end + + % Can we accept the expanded point? + if ( f_e < f_r ) + x(n_dim+1,:) = x_e; + f(n_dim+1 ) = f_e; + if (flag_draw) + figure(2); subplot(1,2,1); title('expansion', 'fontsize',18, 'fontweight','bold') + end + else + x(n_dim+1,:) = x_r; + f(n_dim+1 ) = f_r; + if (flag_draw) + figure(2); subplot(1,2,1); title('eventual reflection', 'fontsize',18, 'fontweight','bold') + end + end + + % 3-3.Outside contraction. + elseif ( f(n_dim) <= f_r && f_r < f(n_dim+1) ) + x_c = (1+rho*gam)*x_bar - rho*gam*x(n_dim+1,:); + f_c = feval(function_handle,x_c); n_feval = n_feval+1; + + if(flag_draw ==1) + draw_image(x_c); + end + + if (f_c <= f_r) % accept the contracted point + x(n_dim+1,:) = x_c; + f(n_dim+1 ) = f_c; + if (flag_draw) + figure(2); subplot(1,2,1); title('outside contraction', 'fontsize',18, 'fontweight','bold') + end + else + [x,f] = shrink(x,function_handle,sig); n_feval = n_feval+n_dim; + if (flag_draw) + figure(2); subplot(1,2,1); title('shrink', 'fontsize',18, 'fontweight','bold') + end + end + + % 3-4. Intra contraction. + else + x_c = ( 1 - gam ) * x_bar + gam * x(n_dim+1,:); + f_c = feval(function_handle,x_c); + n_feval = n_feval+1; + + if(flag_draw ==1) + draw_image(x_c); + end + + % Can we accept the contracted point? + if (f_c < f(n_dim+1)) + x(n_dim+1,:) = x_c; + f(n_dim+1 ) = f_c; + if (flag_draw) + figure(2); subplot(1,2,1); title('inside contraction', 'fontsize',18, 'fontweight','bold') + end + else + [x,f] = shrink(x,function_handle,sig); n_feval = n_feval+n_dim; + if (flag_draw) + figure(2); subplot(1,2,1); title('shrink', 'fontsize',18, 'fontweight','bold') + end + end + end + + % Resort the points. Note that we are not implementing the usual + % Nelder-Mead tie-breaking rules (when f(1) = f(2) or f(n_dim) = + % f(n_dim+1)... + + [ f, index ] = sort ( f ); + x = x(index,:); + + % Test for convergence + converged = f(n_dim+1)-f(1) < tolerance; + + % Test for divergence + diverged = ( max_feval < n_feval ); + + if (flag_draw) + draw_simplex(x); + end + end + + if ( 0 ) + fprintf('The best point x^* was: %d %d\n',x(1,:)); + fprintf('f(x^*) = %d\n',f(1)); + end + + x_opt = x(1,:); + + figure(2); + subplot(1,2,1); + plot(x(1,1),x(1,2),'r*','MarkerSize',14,'linewidth',2.5); + title(''); + + if ( diverged ) + fprintf ( 1, '\n' ); + fprintf ( 1, 'NELDER_MEAD - Warning!\n' ); + fprintf ( 1, ' The maximum number of function evaluations was exceeded\n') + fprintf ( 1, ' without convergence being achieved.\n' ); + end + + return +end + +function f = evaluate ( x, function_handle) + + %*****************************************************************************80 + % + %% EVALUATE handles the evaluation of the function at each point. + % + % Licensing: + % + % This code is distributed under the GNU LGPL license. + % + % Modified: + % + % 19 January 2009 + % + % Author: + % + % Jeff Borggaard + % + % Reference: + % + % John Nelder, Roger Mead, + % A simplex method for function minimization, + % Computer Journal, + % Volume 7, Number 4, January 1965, pages 308-313. + % + % Parameters: + % + % Input, real X(N_DIM+1,N_DIM), the points. + % + % Input, real FUNCTION_HANDLE ( X ), the handle of a MATLAB procedure + % to evaluate the function. + % + % Output, real F(1,NDIM+1), the value of the function at each point. + % + [ ~, n_dim ] = size ( x ); + + f = zeros ( 1, n_dim+1 ); + + for i = 1 : n_dim + 1 + f(i) = feval(function_handle,x(i,:)); + end + + return +end + +function [ x, f ] = shrink ( x, function_handle, sig ) + +%*****************************************************************************80 +% +%% SHRINK shrinks the simplex towards the best point. +% +% Discussion: +% +% In the worst case, we need to shrink the simplex along each edge towards +% the current "best" point. This is quite expensive, requiring n_dim new +% function evaluations. +% +% +% Modified: +% +% 19 January 2009 +% +% Author: +% +% Jeff Borggaard +% +% Reference: +% +% John Nelder, Roger Mead, +% A simplex method for function minimization, +% Computer Journal, +% Volume 7, Number 4, January 1965, pages 308-313. +% +% Parameters: +% +% Input, real X(N_DIM+1,N_DIM), the points. +% +% Input, real FUNCTION_HANDLE ( X ), the handle of a MATLAB procedure +% to evaluate the function. +% +% Input, real SIG, ? +% +% Output, real X(N_DIM+1,N_DIM), the points after shrinking was applied. +% +% Output, real F(1,NDIM+1), the value of the function at each point. +% + [ ~, n_dim ] = size ( x ); + + x1 = x(1,:); + f(1) = feval ( function_handle, x1 ); + + for i = 2 : n_dim + 1 + x(i,:) = sig * x(i,:) + ( 1.0 - sig ) * x(1,:); + f(i) = feval ( function_handle, x(i,:) ); + end + + return +end + + +function draw_image(x) + global Img_path step Flag_Dataset; + step = step + 1; + + figure (2) + subplot(1,2,1); + plot(x(1,1), x(1,2), 'k*', 'MarkerSize', 10, 'linewidth', 1.2); + + subplot(1,2,2); + x_close = FindClosestPoint(x(1,:), Flag_Dataset); + name_Initial_img = strcat('Param-ISO-', int2str(x_close(1,1)), '-ExpT-', int2str(x_close(1,2)), '.jpg'); + path_Initial_image = strcat(Img_path,'\',name_Initial_img); + + Initial_image = imread(path_Initial_image); + imshow(Initial_image); + title_str = strcat('Step : ',num2str(step),' Gain : ', num2str(x(1,1),2) ,'dB,',' ExpT : ', num2str(x(1,2)/1000,4), 'ms' ); + title(title_str, 'fontsize',16, 'fontweight','bold'); + pause(0.1); +end + +function draw_simplex(x) + figure (2) + subplot(1,2,1); + plot(x(1:2,1),x(1:2,2),'r') + plot(x(2:3,1),x(2:3,2),'r') + plot(x([1 3],1),x([1 3],2),'r') + pause(0.1); + plot(x(1:2,1),x(1:2,2),'k') + plot(x(2:3,1),x(2:3,2),'k') + plot(x([1 3],1),x([1 3],2),'k') +end \ No newline at end of file diff --git a/Utils_FeatureMatching/main_feature_matching_analysis.m b/Utils_FeatureMatching/main_feature_matching_analysis.m new file mode 100644 index 0000000..d3e8022 --- /dev/null +++ b/Utils_FeatureMatching/main_feature_matching_analysis.m @@ -0,0 +1,258 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Camera Exposure Control for Robust Robot Vision +% with Noise-Aware Image Assessment Metric +% +% Ukcheol Shin, Jinsun Park, Gyumin Shim, Francois Rameau, and In So Kweon +% +% IROS 2019 +% +% Please feel free to contact if you have any problems. +% +% E-mail : Ukcheol Shin (shinwc159@gmail.com / shinwc159@kaist.ac.kr) +% Robotics and Computer Vision Lab., EE, +% KAIST, Republic of Korea +% +% Project Page : https://sites.google.com/view/noise-aware-exposure-control +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Name : feature_matching_analysis +% : conduct feature extraction & matching expeeriments. +% +% Modified: +% +% 17 December 2019 +% +% Author: +% +% Ukcheol Shin +% +% Input : path_name - path of each metric's result +% output : None +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function [] = main_feature_matching_analysis(path_name) +close all; +clc; + +addpath(genpath('subfunctions')); +result_folder = strcat(path_name,'/result_matching'); +mkdir(result_folder); + +% GT Intrinsic / Extrinsic Parameters +% plz refer the "GT_CameraParameter.txt" of dataset. +K1 = [814.889003, -0.384418, 764.659138; + 0.000000, 814.206990, 576.541219; + 0.000000, 0.000000, 1.000000]; +K2 = [816.254045, -0.516877, 767.769055; + 0.000000, 815.958860, 580.307083; + 0.000000, 0.000000, 1.000000]; + +D1 = [-0.055030, 0.122773, 0.001917, -0.001426, -0.065038]; +D2 = [-0.052789, 0.123278, 0.000337, -0.001296, -0.067356]; + +R = [0.999887, -0.004519, -0.014343; + 0.004515, 0.999990, -0.000323; + 0.014345, 0.000259, 0.999897]; +T = [-0.201597, -0.001746, 0.000769]'; + +width = 1600; +height = 1200; + +%% Initialize rectification map +stereo_rect = cv.stereoRectify(K1, D1, K2, D2, [width, height], R, T, 'Alpha', 0); + +R1 = stereo_rect.R1; +R2 = stereo_rect.R2; +P1 = stereo_rect.P1; +P2 = stereo_rect.P2; + +[map1_1, map1_2] = cv.initUndistortRectifyMap(K1, D1, [width, height], 'R', R1, 'NewCameraMatrix', P1); +[map2_1, map2_2] = cv.initUndistortRectifyMap(K2, D2, [width, height], 'R', R2, 'NewCameraMatrix', P2); + +% Intrinsics and rotation are changed after rectification +K1 = P1(1:3, 1:3); +K2 = P2(1:3, 1:3); +R = eye(3); +T = K2\P2; +T = T(:, 4); +baseline = norm(T); + +%% Parameters for experiment +num_features_max = 100000; +num_features = 1000; + +th_dist = 0.02; % Inlier epipolar distance threshold +th_reproject = 0.1; +th_fast = 10; + +LeftFiles=dir(strcat(path_name,'/left/','*.jpg')); +RightFiles = dir(strcat(path_name,'/right/','*.jpg')); + +if(length(LeftFiles) ~= length(RightFiles)) + error('incorrect folder !!!'); + return; +end + +%% Do feature extractiong & matching +file_name = strcat(result_folder,'/','FeatureMactching_Result.txt'); +fileID = fopen(file_name,'a'); + +for k=1 : length(LeftFiles) + % Check image name consistency + LeftFileNames = LeftFiles(k).name; + RightFileNames = RightFiles(k).name; + + path_image_left = strcat(path_name,'/left/',LeftFileNames); + path_image_right = strcat(path_name,'/right/',RightFileNames); + + index = regexp(LeftFileNames,'_ISO-'); + My_name_left = LeftFileNames(1:index); + index = regexp(RightFileNames,'_ISO-'); + My_name_right = RightFileNames(1:index); + + if(~strcmp(My_name_left,My_name_right)) + error('incorrect file matching!!!'); + break; + end + + % Load images + image_left_orig = imread(path_image_left); + image_right_orig = imread(path_image_right); + + image_left = cv.remap(image_left_orig, map1_1, map1_2); + image_right = cv.remap(image_right_orig, map2_1, map2_2); + + result = struct(); + + %% Comparison 1. Number of FAST extracted + detector_fast = cv.ORB('MaxFeatures', num_features_max, 'ScoreType', 'FAST'); + detector_fast.FastThreshold = th_fast; + + % FAST extraction without limitation + fast_left_max_num = detector_fast.detect(image_left); + fast_right_max_num = detector_fast.detect(image_right); + + result.NumFASTLeftUnlimited = numel(fast_left_max_num); + result.NumFASTRightUnlimited = numel(fast_right_max_num); + + % FAST extraction with limitation + detector = cv.ORB('MaxFeatures', num_features, 'ScoreType', 'FAST'); + detector.FastThreshold = th_fast; + + fast_left_init = detector.detect(image_left); + fast_right_init = detector.detect(image_right); + + num_left_init = numel(fast_left_init); + num_right_init = numel(fast_right_init); + + result.NumFASTLeftInit = num_left_init; + result.NumFASTRightInit = num_right_init; + + % Feature extraction + [desc_left, kp_left] = detector.compute(image_left, fast_left_init); + [desc_right, kp_right] = detector.compute(image_right, fast_right_init); + + result.NumberOfKeyPointsLeft = numel(kp_left); + result.NumberOfKeyPointsRight = numel(kp_right); + + % matcher = cv.DescriptorMatcher('BFMatcher', 'CrossCheck', true); + matcher = cv.DescriptorMatcher('BFMatcher', 'NormType', 'Hamming', 'CrossCheck', true); + + % Initial feature matching + matches = matcher.match(desc_left, desc_right); + num_initial_matches = numel(matches); + + result.NumMatchesInitial = num_initial_matches; + + image_matches_init = cv.drawMatches(image_left, kp_left, image_right, kp_right, matches); + + % Matched left / right indices + pts_left = zeros(3, num_initial_matches); + pts_right = zeros(3, num_initial_matches); + + pts_right_gt = zeros(2, num_initial_matches); + + for k=1:num_initial_matches + % MexOpenCV (Zero-based) -> MATLAB (One-based) + % To normalized coordinates + pts_left(:, k) = K1\[kp_left(matches(k).queryIdx+1).pt'; 1]; + pts_right(:, k) = K2\[kp_right(matches(k).trainIdx+1).pt'; 1]; + + pts_right_gt_tmp = [R, T]*[pts_left(:, k); 1]; + + pts_right_gt(:, k) = [pts_right_gt_tmp(1)/pts_right_gt_tmp(3); ... + pts_right_gt_tmp(2)/pts_right_gt_tmp(3)]; + + end + + pts_left = pts_left(1:2, :)./repmat(pts_left(3, :), [2, 1]); + pts_right = pts_right(1:2, :)./repmat(pts_right(3, :), [2, 1]); + + dist_err = sqrt(sum((pts_right_gt - pts_right).^2, 1)); + flag_match_correct = dist_err < th_reproject; + matches_correct = matches(flag_match_correct); + + num_correct_matches = sum(flag_match_correct); + + result.NumMatchesInitialCorrect = num_correct_matches; + + image_matches_correct = cv.drawMatches(image_left, kp_left, image_right, kp_right, matches_correct); + + %% Step 2. Pose Estimation + E = cv.findEssentialMat(pts_left', pts_right', 'Method', 'LMedS'); + % E = cv.findEssentialMat(pts_left', pts_right', 'Method', 'Ransac', 'Threshold', 0.1); + + [R_init, T_init, num_matches_ransac, flag_good] = cv.recoverPose(E, pts_left', pts_right'); + flag_good = flag_good > 0; + + matches_ransac = matches(flag_good); + pts_left_ransac = pts_left(:, flag_good); + pts_right_ransac = pts_right(:, flag_good); + + result.NumMatchesRANSAC = num_matches_ransac; + + image_matches_ransac = cv.drawMatches(image_left, kp_left, ... + image_right, kp_right, matches_ransac); + + figure(5); + imagesc([image_matches_init; image_matches_ransac; image_matches_correct]); + title(sprintf('Number of initial / LMedS / correct matches : %d -> %d -> %d', ... + result.NumMatchesInitial, result.NumMatchesRANSAC, result.NumMatchesInitialCorrect)); + drawnow; + output = strcat(result_folder,'/',My_name_left); + saveas(gcf,output,'fig'); + saveas(gcf,output,'jpg'); + + % Translation is up-to-scale + T_init = T_init*baseline/norm(T_init); + + R_err_init = real(acosd(0.5*trace(R'*R_init) - 0.5)); + T_err_init = norm(T - T_init); + + result.R_err_init = R_err_init; + result.T_err_init = T_err_init; + + result.R = R; + result.T = T; + result.R_init = R_init; + result.T_init = T_init; + + + %% Result + fprintf(fileID, '==========================================\n'); + fprintf(fileID, '\nMatching and Pose Estimation results\n'); + fprintf(fileID, 'Dataset Path : %s \n', path_name); + fprintf(fileID, 'Result of %s \n', My_name_left); + fprintf(fileID, 'Number of FAST from the left : %d\n', result.NumFASTLeftUnlimited); + fprintf(fileID, 'Number of FAST from the right : %d\n', result.NumFASTRightUnlimited); + fprintf(fileID, 'Number of keypoints from the left : %d\n', result.NumberOfKeyPointsLeft); + fprintf(fileID, 'Number of keypoints from the right : %d\n', result.NumberOfKeyPointsRight); + fprintf(fileID, 'Number of initial matches : %d\n', result.NumMatchesInitial); + fprintf(fileID, 'Number of correct matches : %d\n', result.NumMatchesInitialCorrect); + fprintf(fileID, 'Number of RANSAC matches : %d\n', result.NumMatchesRANSAC); + fprintf(fileID, 'Initial rotation error : %f (deg)\n', result.R_err_init); + fprintf(fileID, 'Initial translation error : %f (m)\n', result.T_err_init); + fprintf(fileID, '==========================================\n'); +end + +fclose(fileID); +end \ No newline at end of file diff --git a/Utils_FeatureMatching/subfunctions/KeyPointNMS.m b/Utils_FeatureMatching/subfunctions/KeyPointNMS.m new file mode 100644 index 0000000..4bacd58 --- /dev/null +++ b/Utils_FeatureMatching/subfunctions/KeyPointNMS.m @@ -0,0 +1,40 @@ +% KEYPOINTNMS Do non-maximum suppression on keypoints inside a grid +% +% Inputs +% grid_range - Grid range [x1, y1, x2, y2] +% pt - Keypoints +% num - Number of keypoints to preserve +% Outputs +% idx - Indices of the survived keypoint +function idx = KeyPointNMS(grid_range, kp, num) + x1 = grid_range(1); + y1 = grid_range(2); + x2 = grid_range(3); + y2 = grid_range(4); + + num_kp = numel(kp); + + x = zeros(num_kp, 1); + y = zeros(num_kp, 1); + s = zeros(num_kp, 1); + + for k=1:num_kp + x(k) = kp(k).pt(1); + y(k) = kp(k).pt(2); + s(k) = kp(k).response; + end + + idx_inside = find((x >= x1) & (x < x2) & (y >= y1) & (y < y2)); + + if(numel(idx_inside) <= num) + idx = idx_inside; + return; + end + + score_inside = s(idx_inside); + + [~, idx_sorted] = sort(score_inside, 'descend'); + + idx = idx_inside(idx_sorted(1:num)); + +end \ No newline at end of file diff --git a/Utils_FeatureMatching/subfunctions/SymmetricEpipolarDistance.m b/Utils_FeatureMatching/subfunctions/SymmetricEpipolarDistance.m new file mode 100644 index 0000000..ef750f8 --- /dev/null +++ b/Utils_FeatureMatching/subfunctions/SymmetricEpipolarDistance.m @@ -0,0 +1,29 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Name : SymmetricEpipolarDistance +% Input : E - Essential matrix +% x1 - normalized image points from the 1st camera [3 x N] +% x2 - normalized image points from the 2nd camera [3 x N] +% th - distance threshold for inliers +% Output : D - sum of distances +% flag_inliers - flags of inliners +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function [D, flag_inliers] = SymmetricEpipolarDistance(F, x1, x2, th) + +% Epipolar lines +l1 = F'*x2; +l2 = F*x1; + +l1 = l1./repmat(sqrt(sum(l1(1:2,:).^2, 1)), [3, 1]); +l2 = l2./repmat(sqrt(sum(l2(1:2,:).^2, 1)), [3, 1]); + +% Distance +d1 = sqrt(sum(l1.*x1, 1).^2); +d2 = sqrt(sum(l2.*x2, 1).^2); + +d = (d1 + d2); + +flag_inliers = d < th; + +D = sum(d(:)); + +return \ No newline at end of file diff --git a/Utils_FeatureMatching/subfunctions/ValidCameraPosition.m b/Utils_FeatureMatching/subfunctions/ValidCameraPosition.m new file mode 100644 index 0000000..ce8eea8 --- /dev/null +++ b/Utils_FeatureMatching/subfunctions/ValidCameraPosition.m @@ -0,0 +1,73 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Name : ValidCameraPosition +% Input : E - essential matrix +% P1 - normalized camera matrix of the 1st camera [R | T] +% x1 - normalized points of the 1st camera [2 x N] +% x2 - normalized points of the 2nd camera [2 x N] +% Output : P2 - normalized camera matrix of the 2nd camera [R | T] +% R - rotation matrix +% T - translation matrix +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function [P2, R, T] = ValidCameraPosition(E, P1, x1, x2) +[U, ~, V] = svd(E); + +W = [0, -1, 0; 1, 0, 0; 0, 0, 1]; +u3 = U(:,3); + +% 4 possible positions +P21 = [U*W*V', u3]; +P22 = [U*W*V', -u3]; +P23 = [U*W'*V', u3]; +P24 = [U*W'*V', -u3]; + +P = {P21, P22, P23, P24}; + +P_ref = [eye(3,3), zeros(3,1)]; + +P2 = []; +R = []; +T = []; + +N = size(x1, 2); +num_valid = 0; + +for k=1:4 + X = zeros(4,N); + + for n=1:N + A = [x1(1)*P_ref(3,:) - P_ref(1,:); + x1(2)*P_ref(3,:) - P_ref(2,:); + x2(1)*P{k}(3,:) - P{k}(1,:); + x2(2)*P{k}(3,:) - P{k}(2,:)]; + + [~, ~, V] = svd(A); + X(:,n) = V(:,end); + end + + % Projected points + xp1 = P_ref*X; + xp2 = P{k}*X; + + d1 = (sign(det(squeeze(P_ref(:,1:3))))*xp1(3,:))./(X(4,:)*norm(P_ref(3,:))); + d2 = (sign(det(squeeze(P{k}(:,1:3))))*xp2(3,:))./(X(4,:)*norm(P{k}(3,:))); + + num_pos = sum((d1 > 0) & (d2 > 0)); + + if((num_pos > 0) && (num_pos > num_valid)) + num_valid = num_pos; + + P_tmp = P{k}*[P1; [0, 0, 0, 1]]; + + R = P_tmp(:,1:3); + T = P_tmp(:,4); + + R_det = det(R); + + R = R/R_det; + T = T/R_det; + + P2 = [R, T]; + end +end + +return; \ No newline at end of file diff --git a/Utils_FeatureMatching/subfunctions/calculateReprojectionError.m b/Utils_FeatureMatching/subfunctions/calculateReprojectionError.m new file mode 100644 index 0000000..1510640 --- /dev/null +++ b/Utils_FeatureMatching/subfunctions/calculateReprojectionError.m @@ -0,0 +1,46 @@ +% CALCULATEREPROJECTIONERROR Calculate reprojection error +% +% Inputs +% params - Input rotation and translation vectors [R(3), T(3)] +% pts_left - Left keypoints [3 x N] +% pts_right - Right keypoints [3 x N] +% +% Outputs +% err - Calculated reprojection error +function err = calculateReprojectionError(params, T, pts_left, pts_right) + R = rotationVectorToMatrix(params(1:3))'; +% T = params(4:6)'; + + T_mat = [ 0, -T(3), T(2); + T(3), 0, -T(1); + -T(2), T(1), 0]; + + E = R*T_mat; + + num = size(pts_left, 2); + if(size(pts_right, 2) ~= num) + error('Number of size must be the same'); + end + + pts_left = [pts_left; ones(1, num)]; + pts_right = [pts_right; ones(1, num)]; + + l1 = E'*pts_right; + l2 = E*pts_left; + + l1_norm = sqrt(sum(l1.^2, 1)); + l2_norm = sqrt(sum(l2.^2, 1)); + + l1 = l1./repmat(l1_norm, [3, 1]); + l2 = l2./repmat(l2_norm, [3, 1]); + + d1 = abs(sum(l1.*pts_left, 1)); + d2 = abs(sum(l2.*pts_right, 1)); + + err = (d1(:) + d2(:))/2; +% err = logLoss(err); +end + +% function err_out = logLoss(err_in) +% err_out = log(err_in + 1); +% end \ No newline at end of file diff --git a/Utils_FeatureMatching/subfunctions/calibrated_fivepoint.m b/Utils_FeatureMatching/subfunctions/calibrated_fivepoint.m new file mode 100644 index 0000000..d148808 --- /dev/null +++ b/Utils_FeatureMatching/subfunctions/calibrated_fivepoint.m @@ -0,0 +1,100 @@ +function Evec = calibrated_fivepoint( Q1,Q2) +% Function Evec = calibrated_fivepoint( Q1,Q2) +% Henrik Stewenius 20040722 +% +% +% ARTICLE{stewenius-engels-nister-isprsj-2006, +% AUTHOR = {H. Stew\'enius and C. Engels and D. Nist\'er}, +% TITLE = {Recent Developments on Direct Relative Orientation}, +% JOURNAL = {ISPRS Journal of Photogrammetry and Remote Sensing}, +% URL = {http://dx.doi.org/10.1016/j.isprsjprs.2006.03.005}, +% VOLUME = {60}, +% ISSUE = {4}, +% PAGES = {284--294}, +% MONTH = JUN, +% CODE = {http://vis.uky.edu/~stewe/FIVEPOINT}, +% PDF = {http://www.vis.uky.edu/~stewe/publications/stewenius_engels_nister_5pt_isprs.pdf}, +% YEAR = 2006 +%} +% +% +% For more information please see: +% Grobner Basis Methods for Minimal Problems in Computer Vision +% Henrik Stewenius, +% PhD Thesis, Lund University, 2005 +% http://www.maths.lth.se/matematiklth/personal/stewe/THESIS/ +% +% +% If this implementation is too slow for your needs please see: +% An Efficient Solution to the Five-Point Relative Pose +% +%@Article{ nister-itpam-04, +% author = {Nist\'er, D.}, +% journal = pami, +% month = {June}, +% number = {6}, +% title = {Problem}, +% pages = {756-770}, +% volume = {26}, +% year = {2004} +%} +% +% +% +% +% Code to veryfy that it works: +% Q1 = rand(3,5); +% Q2 = rand(3,5); +% Evec = calibrated_fivepoint( Q1,Q2); +% for i=1:size(Evec,2) +% E = reshape(Evec(:,i),3,3); +% % Check determinant constraint! +% det( E) +% % Check trace constraint +% 2 *E*transpose(E)*E -trace( E*transpose(E))*E +% % Check reprojection errors +% diag( Q1'*E*Q2) +% end +% +% PS: Please note that due to varying standards of which is Q1 and Q2 +% it is very possible that you get essential matrices which are +% the transpose of what your expected. + + +%1 Pose linear equations for the essential matrix. +Q1 = Q1'; +Q2 = Q2'; + +Q = [Q1(:,1).*Q2(:,1) , ... + Q1(:,2).*Q2(:,1) , ... + Q1(:,3).*Q2(:,1) , ... + Q1(:,1).*Q2(:,2) , ... + Q1(:,2).*Q2(:,2) , ... + Q1(:,3).*Q2(:,2) , ... + Q1(:,1).*Q2(:,3) , ... + Q1(:,2).*Q2(:,3) , ... + Q1(:,3).*Q2(:,3) ] ; + + +[U,S,V] = svd(Q,0); +EE = V(:,6:9); + +A = calibrated_fivepoint_helper( EE ) ; +warning('off', 'MATLAB:nearlySingularMatrix'); +A = A(:,1:10)\A(:,11:20); +warning('on', 'MATLAB:nearlySingularMatrix'); +M = -A([1 2 3 5 6 8], :); + +M(7,1) = 1; +M(8,2) = 1; +M(9,4) = 1; +M(10,7) = 1; + +[V,D] = eig(M ); +SOLS = V(7:9,:)./(ones(3,1)*V(10,:)); + +Evec = EE*[SOLS ; ones(1,10 ) ]; +Evec = Evec./ ( ones(9,1)*sqrt(sum( Evec.^2))); + +I = find(not(imag( Evec(1,:) ))); +Evec = Evec(:,I); diff --git a/Utils_FeatureMatching/subfunctions/calibrated_fivepoint_helper.c b/Utils_FeatureMatching/subfunctions/calibrated_fivepoint_helper.c new file mode 100644 index 0000000..cd9db55 --- /dev/null +++ b/Utils_FeatureMatching/subfunctions/calibrated_fivepoint_helper.c @@ -0,0 +1,380 @@ +/* +Copyright Henrik Stewenius. + + +This Code was written for the paper: + +@ARTICLE{stewenius-engels-nister-isprsj-2006, + AUTHOR = {H. Stew\'enius and C. Engels and D. Nist\'er}, + TITLE = {Recent Developments on Direct Relative Orientation}, + JOURNAL = {ISPRS Journal of Photogrammetry and Remote Sensing}, + URL = {http://dx.doi.org/10.1016/j.isprsjprs.2006.03.005}, + VOLUME = {60}, + ISSUE = {4}, + PAGES = {284--294}, + MONTH = JUN, + CODE = {http://vis.uky.edu/~stewe/FIVEPOINT}, + PDF = {http://www.vis.uky.edu/~stewe/publications/stewenius_engels_nister_5pt_isprs.pdf}, + YEAR = 2006 +} + + You are free to use this code for academic research as long as you + refer to this paper. Commercial licence can be negotiated. Though if + you really want to use this in a product there are certain optimizations + which you would want. +*/ + + + +/************************************************* + Indata : 10x4 matrix + Data out: 10x20 matrix +*************************************************/ +#include "mex.h" +#include + + +void mexFunction(int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[]) +/*nlhs number of expected mxArrays. + plhs pointer to an array of NULL pointers. + nrhs number of input mxArrays. + prhs pointer to an array of input mxArrays. */ +{ + double *EE, *A; + double e00,e01,e02,e03,e04,e05,e06,e07,e08; + double e10,e11,e12,e13,e14,e15,e16,e17,e18; + double e20,e21,e22,e23,e24,e25,e26,e27,e28; + double e30,e31,e32,e33,e34,e35,e36,e37,e38; + + double e002,e012,e022,e032,e042,e052,e062,e072,e082; + double e102,e112,e122,e132,e142,e152,e162,e172,e182; + double e202,e212,e222,e232,e242,e252,e262,e272,e282; + double e302,e312,e322,e332,e342,e352,e362,e372,e382; + + double e003,e013,e023,e033,e043,e053,e063,e073,e083; + double e103,e113,e123,e133,e143,e153,e163,e173,e183; + double e203,e213,e223,e233,e243,e253,e263,e273,e283; + double e303,e313,e323,e333,e343,e353,e363,e373,e383; + + if(nrhs != 1 ) mexErrMsgTxt("EE (10*4)\n"); + EE = mxGetPr( prhs[0] ) ; + plhs[0] = mxCreateDoubleMatrix(10 ,20 , mxREAL); + A = mxGetPr( plhs[0]); + + +e00 = EE[0*9 + 0 ]; +e10 = EE[1*9 + 0 ]; +e20 = EE[2*9 + 0 ]; +e30 = EE[3*9 + 0 ]; +e01 = EE[0*9 + 1 ]; +e11 = EE[1*9 + 1 ]; +e21 = EE[2*9 + 1 ]; +e31 = EE[3*9 + 1 ]; +e02 = EE[0*9 + 2 ]; +e12 = EE[1*9 + 2 ]; +e22 = EE[2*9 + 2 ]; +e32 = EE[3*9 + 2 ]; +e03 = EE[0*9 + 3 ]; +e13 = EE[1*9 + 3 ]; +e23 = EE[2*9 + 3 ]; +e33 = EE[3*9 + 3 ]; +e04 = EE[0*9 + 4 ]; +e14 = EE[1*9 + 4 ]; +e24 = EE[2*9 + 4 ]; +e34 = EE[3*9 + 4 ]; +e05 = EE[0*9 + 5 ]; +e15 = EE[1*9 + 5 ]; +e25 = EE[2*9 + 5 ]; +e35 = EE[3*9 + 5 ]; +e06 = EE[0*9 + 6 ]; +e16 = EE[1*9 + 6 ]; +e26 = EE[2*9 + 6 ]; +e36 = EE[3*9 + 6 ]; +e07 = EE[0*9 + 7 ]; +e17 = EE[1*9 + 7 ]; +e27 = EE[2*9 + 7 ]; +e37 = EE[3*9 + 7 ]; +e08 = EE[0*9 + 8 ]; +e18 = EE[1*9 + 8 ]; +e28 = EE[2*9 + 8 ]; +e38 = EE[3*9 + 8 ]; + + +e002 =e00*e00; +e102 =e10*e10; +e202 =e20*e20; +e302 =e30*e30; +e012 =e01*e01; +e112 =e11*e11; +e212 =e21*e21; +e312 =e31*e31; +e022 =e02*e02; +e122 =e12*e12; +e222 =e22*e22; +e322 =e32*e32; +e032 =e03*e03; +e132 =e13*e13; +e232 =e23*e23; +e332 =e33*e33; +e042 =e04*e04; +e142 =e14*e14; +e242 =e24*e24; +e342 =e34*e34; +e052 =e05*e05; +e152 =e15*e15; +e252 =e25*e25; +e352 =e35*e35; +e062 =e06*e06; +e162 =e16*e16; +e262 =e26*e26; +e362 =e36*e36; +e072 =e07*e07; +e172 =e17*e17; +e272 =e27*e27; +e372 =e37*e37; +e082 =e08*e08; +e182 =e18*e18; +e282 =e28*e28; +e382 =e38*e38; + +e003 =e00*e00*e00; +e103 =e10*e10*e10; +e203 =e20*e20*e20; +e303 =e30*e30*e30; +e013 =e01*e01*e01; +e113 =e11*e11*e11; +e213 =e21*e21*e21; +e313 =e31*e31*e31; +e023 =e02*e02*e02; +e123 =e12*e12*e12; +e223 =e22*e22*e22; +e323 =e32*e32*e32; +e033 =e03*e03*e03; +e133 =e13*e13*e13; +e233 =e23*e23*e23; +e333 =e33*e33*e33; +e043 =e04*e04*e04; +e143 =e14*e14*e14; +e243 =e24*e24*e24; +e343 =e34*e34*e34; +e053 =e05*e05*e05; +e153 =e15*e15*e15; +e253 =e25*e25*e25; +e353 =e35*e35*e35; +e063 =e06*e06*e06; +e163 =e16*e16*e16; +e263 =e26*e26*e26; +e363 =e36*e36*e36; +e073 =e07*e07*e07; +e173 =e17*e17*e17; +e273 =e27*e27*e27; +e373 =e37*e37*e37; +e083 =e08*e08*e08; +e183 =e18*e18*e18; +e283 =e28*e28*e28; +e383 =e38*e38*e38; + + +A[0 + 10*0]=0.5*e003+0.5*e00*e012+0.5*e00*e022+0.5*e00*e032+e03*e01*e04+e03*e02*e05+0.5*e00*e062+e06*e01*e07+e06*e02*e08-0.5*e00*e042-0.5*e00*e052-0.5*e00*e072-0.5*e00*e082; +A[0 + 10*1]=e00*e11*e01+e00*e12*e02+e03*e00*e13+e03*e11*e04+e03*e01*e14+e03*e12*e05+e03*e02*e15+e13*e01*e04+e13*e02*e05+e06*e00*e16+1.5*e10*e002+0.5*e10*e012+0.5*e10*e022+0.5*e10*e062-0.5*e10*e042-0.5*e10*e052-0.5*e10*e072+0.5*e10*e032+e06*e11*e07+e06*e01*e17+e06*e12*e08+e06*e02*e18+e16*e01*e07+e16*e02*e08-e00*e14*e04-e00*e17*e07-e00*e15*e05-e00*e18*e08-0.5*e10*e082; +A[0 + 10*2]=e16*e02*e18+e03*e12*e15+e10*e11*e01+e10*e12*e02+e03*e10*e13+e03*e11*e14+e13*e11*e04+e13*e01*e14+e13*e12*e05+e13*e02*e15+e06*e10*e16+e06*e12*e18+e06*e11*e17+e16*e11*e07+e16*e01*e17+e16*e12*e08-e10*e14*e04-e10*e17*e07-e10*e15*e05-e10*e18*e08+1.5*e00*e102+0.5*e00*e122+0.5*e00*e112+0.5*e00*e132+0.5*e00*e162-0.5*e00*e152-0.5*e00*e172-0.5*e00*e182-0.5*e00*e142; +A[0 + 10*3]=0.5*e103+0.5*e10*e122+0.5*e10*e112+0.5*e10*e132+e13*e12*e15+e13*e11*e14+0.5*e10*e162+e16*e12*e18+e16*e11*e17-0.5*e10*e152-0.5*e10*e172-0.5*e10*e182-0.5*e10*e142; +A[0 + 10*4]=-e00*e28*e08-e00*e25*e05-e00*e27*e07-e00*e24*e04+e26*e02*e08+e26*e01*e07+e06*e02*e28+e06*e22*e08+e06*e01*e27+e06*e21*e07+e23*e02*e05+e23*e01*e04+e03*e02*e25+e03*e22*e05+e03*e01*e24+e03*e21*e04+e00*e22*e02+e00*e21*e01-0.5*e20*e082-0.5*e20*e052-0.5*e20*e072-0.5*e20*e042+e06*e00*e26+0.5*e20*e062+e03*e00*e23+0.5*e20*e022+1.5*e20*e002+0.5*e20*e032+0.5*e20*e012; +A[0 + 10*5]=-e10*e24*e04-e10*e27*e07-e10*e25*e05-e10*e28*e08-e20*e14*e04-e20*e17*e07-e20*e15*e05-e20*e18*e08-e00*e24*e14-e00*e25*e15-e00*e27*e17-e00*e28*e18+e06*e21*e17+e06*e22*e18+e06*e12*e28+e16*e00*e26+e16*e21*e07+e16*e01*e27+e16*e22*e08+e16*e02*e28+e26*e11*e07+e26*e01*e17+e26*e12*e08+e26*e02*e18+e06*e11*e27+e23*e11*e04+e23*e01*e14+e23*e12*e05+e23*e02*e15+e06*e20*e16+e06*e10*e26+e03*e21*e14+e03*e22*e15+e03*e12*e25+e13*e00*e23+e13*e21*e04+e13*e01*e24+e13*e22*e05+e13*e02*e25+e03*e11*e24+e03*e20*e13+e03*e10*e23+e00*e21*e11+3*e00*e20*e10+e00*e22*e12+e20*e12*e02+e20*e11*e01+e10*e22*e02+e10*e21*e01; +A[0 + 10*6]=-0.5*e20*e152+e26*e11*e17-e10*e24*e14-e10*e25*e15-e10*e27*e17-e10*e28*e18+0.5*e20*e162+e13*e10*e23+e13*e22*e15+e23*e12*e15+e23*e11*e14+e16*e10*e26+e16*e21*e17+e16*e11*e27+e16*e22*e18+e16*e12*e28+e26*e12*e18+e13*e12*e25+0.5*e20*e132+1.5*e20*e102+0.5*e20*e122+0.5*e20*e112+e10*e21*e11+e10*e22*e12+e13*e11*e24-0.5*e20*e172-0.5*e20*e182-0.5*e20*e142+e13*e21*e14; +A[0 + 10*7]=-e20*e25*e05-e20*e28*e08-0.5*e00*e272-0.5*e00*e282-0.5*e00*e242+0.5*e00*e262-0.5*e00*e252+e06*e20*e26+0.5*e00*e232+e06*e22*e28+e06*e21*e27+e26*e21*e07+e26*e01*e27+e26*e22*e08+e26*e02*e28-e20*e24*e04-e20*e27*e07+e03*e20*e23+e03*e22*e25+e03*e21*e24+e23*e21*e04+e23*e01*e24+e23*e22*e05+e23*e02*e25+e20*e21*e01+e20*e22*e02+1.5*e00*e202+0.5*e00*e222+0.5*e00*e212; +A[0 + 10*8]=e23*e21*e14+e23*e11*e24+e23*e22*e15+e23*e12*e25+e16*e20*e26+e16*e22*e28+e16*e21*e27+e26*e21*e17+e26*e11*e27+e26*e22*e18+e26*e12*e28+1.5*e10*e202+0.5*e10*e222+0.5*e10*e212+0.5*e10*e232+e20*e21*e11+e20*e22*e12+e13*e20*e23+e13*e22*e25+e13*e21*e24-e20*e24*e14-e20*e25*e15-e20*e27*e17-e20*e28*e18-0.5*e10*e272-0.5*e10*e282-0.5*e10*e242-0.5*e10*e252+0.5*e10*e262; +A[0 + 10*9]=0.5*e203+0.5*e20*e222+0.5*e20*e212+0.5*e20*e232+e23*e22*e25+e23*e21*e24+0.5*e20*e262+e26*e22*e28+e26*e21*e27-0.5*e20*e252-0.5*e20*e272-0.5*e20*e282-0.5*e20*e242; +A[0 + 10*10]=e06*e32*e08-0.5*e30*e082-0.5*e30*e042-0.5*e30*e052-0.5*e30*e072+0.5*e30*e012+0.5*e30*e022+0.5*e30*e032+0.5*e30*e062+1.5*e30*e002+e00*e31*e01+e00*e32*e02+e03*e31*e04+e03*e01*e34+e03*e32*e05+e03*e02*e35+e33*e01*e04+e33*e02*e05+e06*e00*e36+e06*e31*e07+e06*e01*e37+e06*e02*e38+e36*e01*e07+e36*e02*e08-e00*e34*e04-e00*e37*e07-e00*e35*e05-e00*e38*e08+e03*e00*e33; +A[0 + 10*11]=e06*e30*e16+e03*e30*e13+e16*e31*e07+e06*e10*e36-e10*e37*e07+3*e00*e30*e10+e00*e32*e12-e00*e38*e18-e10*e34*e04-e10*e35*e05-e10*e38*e08-e30*e14*e04-e30*e17*e07-e30*e15*e05-e30*e18*e08+e00*e31*e11+e10*e31*e01+e10*e32*e02+e30*e11*e01+e30*e12*e02+e03*e10*e33-e00*e34*e14-e00*e35*e15-e00*e37*e17+e03*e31*e14+e03*e11*e34+e03*e32*e15+e03*e12*e35+e13*e00*e33+e13*e31*e04+e13*e01*e34+e13*e32*e05+e13*e02*e35+e33*e11*e04+e33*e01*e14+e33*e12*e05+e33*e02*e15+e06*e31*e17+e06*e11*e37+e06*e32*e18+e06*e12*e38+e16*e00*e36+e16*e01*e37+e16*e32*e08+e16*e02*e38+e36*e11*e07+e36*e01*e17+e36*e12*e08+e36*e02*e18; +A[0 + 10*12]=e13*e10*e33+e33*e11*e14+e16*e10*e36+e16*e31*e17+e16*e11*e37+e16*e32*e18+e16*e12*e38+e36*e12*e18+e36*e11*e17-e10*e34*e14-e10*e35*e15-e10*e37*e17-e10*e38*e18+e10*e31*e11+e10*e32*e12+e13*e31*e14+e13*e11*e34+e13*e32*e15+e13*e12*e35+e33*e12*e15+1.5*e30*e102+0.5*e30*e122+0.5*e30*e112+0.5*e30*e132+0.5*e30*e162-0.5*e30*e152-0.5*e30*e172-0.5*e30*e182-0.5*e30*e142; +A[0 + 10*13]=e00*e32*e22+3*e00*e30*e20+e00*e31*e21+e20*e31*e01+e20*e32*e02+e30*e21*e01+e30*e22*e02+e03*e20*e33+e03*e32*e25+e03*e22*e35+e03*e31*e24+e03*e21*e34+e23*e00*e33+e23*e31*e04+e23*e01*e34+e23*e32*e05+e23*e02*e35+e33*e21*e04+e33*e01*e24+e33*e22*e05+e33*e02*e25+e06*e30*e26+e06*e20*e36+e06*e32*e28+e06*e22*e38+e06*e31*e27+e06*e21*e37+e26*e00*e36+e26*e31*e07+e03*e30*e23+e26*e01*e37+e26*e32*e08+e26*e02*e38+e36*e21*e07+e36*e01*e27+e36*e22*e08+e36*e02*e28-e00*e35*e25-e00*e37*e27-e00*e38*e28-e00*e34*e24-e20*e34*e04-e20*e37*e07-e20*e35*e05-e20*e38*e08-e30*e24*e04-e30*e27*e07-e30*e25*e05-e30*e28*e08; +A[0 + 10*14]=e16*e30*e26+e13*e21*e34+3*e10*e30*e20+e10*e32*e22+e10*e31*e21+e20*e31*e11+e20*e32*e12+e30*e21*e11+e30*e22*e12+e13*e30*e23+e13*e20*e33+e13*e32*e25+e13*e22*e35+e13*e31*e24+e23*e10*e33+e23*e31*e14+e23*e11*e34+e23*e32*e15+e23*e12*e35+e33*e21*e14+e33*e11*e24+e33*e22*e15+e33*e12*e25+e16*e20*e36+e16*e32*e28+e16*e22*e38+e16*e31*e27+e16*e21*e37+e26*e10*e36+e26*e31*e17+e26*e11*e37+e26*e32*e18+e26*e12*e38+e36*e21*e17+e36*e11*e27+e36*e22*e18+e36*e12*e28-e10*e35*e25-e10*e37*e27-e10*e38*e28-e10*e34*e24-e20*e34*e14-e20*e35*e15-e20*e37*e17-e20*e38*e18-e30*e24*e14-e30*e25*e15-e30*e27*e17-e30*e28*e18; +A[0 + 10*15]=-e20*e34*e24+0.5*e30*e262-0.5*e30*e252-0.5*e30*e272-0.5*e30*e282-0.5*e30*e242+1.5*e30*e202+0.5*e30*e222+0.5*e30*e212+0.5*e30*e232+e20*e32*e22+e20*e31*e21+e23*e20*e33+e23*e32*e25+e23*e22*e35+e23*e31*e24+e23*e21*e34+e33*e22*e25+e33*e21*e24+e26*e20*e36+e26*e32*e28+e26*e22*e38+e26*e31*e27+e26*e21*e37+e36*e22*e28+e36*e21*e27-e20*e35*e25-e20*e37*e27-e20*e38*e28; +A[0 + 10*16]=0.5*e00*e322+e30*e32*e02+e30*e31*e01+1.5*e00*e302+0.5*e00*e312+e03*e32*e35+e33*e31*e04+e33*e01*e34+e33*e32*e05+e33*e02*e35+e06*e30*e36+e06*e31*e37+e06*e32*e38+e36*e31*e07+e36*e01*e37+e36*e32*e08+e36*e02*e38-e30*e34*e04-e30*e37*e07-e30*e35*e05-e30*e38*e08+0.5*e00*e332+0.5*e00*e362-0.5*e00*e382-0.5*e00*e352-0.5*e00*e342-0.5*e00*e372+e03*e30*e33+e03*e31*e34; +A[0 + 10*17]=0.5*e10*e362-0.5*e10*e382-0.5*e10*e352-0.5*e10*e342-0.5*e10*e372+e36*e31*e17+e36*e11*e37+e36*e32*e18+e36*e12*e38-e30*e34*e14-e30*e35*e15-e30*e37*e17-e30*e38*e18+1.5*e10*e302+0.5*e10*e312+0.5*e10*e322+0.5*e10*e332+e30*e31*e11+e30*e32*e12+e13*e30*e33+e13*e31*e34+e13*e32*e35+e33*e31*e14+e33*e11*e34+e33*e32*e15+e33*e12*e35+e16*e30*e36+e16*e31*e37+e16*e32*e38; +A[0 + 10*18]=e33*e31*e24+e33*e21*e34+e26*e30*e36+e26*e31*e37+e26*e32*e38+e36*e32*e28+e36*e22*e38+e36*e31*e27+e36*e21*e37-e30*e35*e25-e30*e37*e27-e30*e38*e28-e30*e34*e24+e33*e22*e35+1.5*e20*e302+0.5*e20*e312+0.5*e20*e322+0.5*e20*e332+0.5*e20*e362-0.5*e20*e382-0.5*e20*e352-0.5*e20*e342-0.5*e20*e372+e30*e32*e22+e30*e31*e21+e23*e30*e33+e23*e31*e34+e23*e32*e35+e33*e32*e25; +A[0 + 10*19]=0.5*e303+0.5*e30*e312+0.5*e30*e322+0.5*e30*e332+e33*e31*e34+e33*e32*e35+0.5*e30*e362+e36*e31*e37+e36*e32*e38-0.5*e30*e382-0.5*e30*e352-0.5*e30*e342-0.5*e30*e372; +A[1 + 10*0]=e00*e01*e04+0.5*e002*e03+e00*e02*e05+0.5*e033+0.5*e03*e042+0.5*e03*e052+0.5*e03*e062+e06*e04*e07+e06*e05*e08-0.5*e03*e012-0.5*e03*e072-0.5*e03*e022-0.5*e03*e082; +A[1 + 10*1]=e03*e14*e04+e10*e01*e04+e16*e05*e08+e00*e10*e03+e00*e11*e04+e00*e01*e14+e00*e12*e05+e00*e02*e15+e10*e02*e05+e03*e15*e05+e06*e03*e16+e06*e14*e07+e06*e04*e17+e06*e15*e08+e06*e05*e18+0.5*e002*e13+1.5*e13*e032+0.5*e13*e042+0.5*e13*e052+0.5*e13*e062-0.5*e13*e012-0.5*e13*e072-0.5*e13*e022-0.5*e13*e082+e16*e04*e07-e03*e12*e02-e03*e11*e01-e03*e17*e07-e03*e18*e08; +A[1 + 10*2]=-e13*e11*e01+e00*e10*e13+e00*e12*e15+e00*e11*e14+e10*e11*e04+e10*e01*e14+e10*e12*e05+e10*e02*e15+e13*e14*e04+e13*e15*e05+e06*e13*e16+e06*e15*e18+e06*e14*e17+e16*e14*e07+e16*e04*e17+e16*e15*e08+e16*e05*e18-e13*e12*e02-e13*e17*e07-e13*e18*e08+0.5*e102*e03+1.5*e03*e132+0.5*e03*e152+0.5*e03*e142+0.5*e03*e162-0.5*e03*e112-0.5*e03*e172-0.5*e03*e122-0.5*e03*e182; +A[1 + 10*3]=0.5*e102*e13+e10*e11*e14+e10*e12*e15+0.5*e133+0.5*e13*e152+0.5*e13*e142+0.5*e13*e162+e16*e15*e18+e16*e14*e17-0.5*e13*e112-0.5*e13*e122-0.5*e13*e172-0.5*e13*e182; +A[1 + 10*4]=-e03*e28*e08-e03*e27*e07-e03*e21*e01-e03*e22*e02+e26*e05*e08+e26*e04*e07+e06*e05*e28+e06*e25*e08+e06*e04*e27+e06*e24*e07+e03*e25*e05+e03*e24*e04+e20*e02*e05+e20*e01*e04+e00*e02*e25+e00*e22*e05+e00*e01*e24+e00*e21*e04+e00*e20*e03-0.5*e23*e072-0.5*e23*e082-0.5*e23*e022-0.5*e23*e012+e06*e03*e26+0.5*e23*e052+0.5*e23*e062+1.5*e23*e032+0.5*e23*e042+0.5*e002*e23; +A[1 + 10*5]=e00*e21*e14+e00*e11*e24+e00*e10*e23+e00*e22*e15+e00*e12*e25+e20*e12*e05+e20*e01*e14+e20*e11*e04+e00*e20*e13+e10*e02*e25+e10*e22*e05+e10*e01*e24+e10*e21*e04+e10*e20*e03+e23*e15*e05+e23*e14*e04+e13*e25*e05+e13*e24*e04+e03*e24*e14+e03*e25*e15+3*e03*e23*e13+e20*e02*e15+e16*e03*e26+e06*e14*e27-e23*e18*e08+e06*e24*e17+e06*e15*e28+e06*e25*e18+e06*e13*e26+e06*e23*e16+e26*e04*e17+e26*e14*e07+e16*e05*e28+e16*e25*e08+e16*e04*e27+e16*e24*e07-e03*e22*e12-e03*e21*e11+e26*e05*e18+e26*e15*e08-e03*e27*e17-e03*e28*e18-e13*e22*e02-e13*e28*e08-e13*e27*e07-e13*e21*e01-e23*e17*e07-e23*e11*e01-e23*e12*e02; +A[1 + 10*6]=-0.5*e23*e182-0.5*e23*e172-0.5*e23*e112-0.5*e23*e122-e13*e22*e12-e13*e27*e17-e13*e28*e18+e26*e15*e18+e26*e14*e17-e13*e21*e11+e20*e12*e15+e13*e25*e15+e13*e24*e14+e16*e13*e26+e16*e25*e18+e16*e15*e28+e16*e24*e17+e16*e14*e27+1.5*e23*e132+0.5*e23*e152+0.5*e23*e142+0.5*e23*e162+e10*e20*e13+e10*e21*e14+e10*e11*e24+e10*e22*e15+e10*e12*e25+e20*e11*e14+0.5*e102*e23; +A[1 + 10*7]=e26*e04*e27+e00*e22*e25-e23*e28*e08+0.5*e03*e262-0.5*e03*e212-0.5*e03*e272-0.5*e03*e222-0.5*e03*e282+e23*e24*e04+e23*e25*e05+0.5*e202*e03+e06*e23*e26+e06*e24*e27+e06*e25*e28+e26*e24*e07+e26*e25*e08+e26*e05*e28-e23*e22*e02-e23*e21*e01-e23*e27*e07+e00*e20*e23+e00*e21*e24+e20*e21*e04+e20*e01*e24+e20*e22*e05+e20*e02*e25+1.5*e03*e232+0.5*e03*e242+0.5*e03*e252; +A[1 + 10*8]=e20*e11*e24-0.5*e13*e212-0.5*e13*e272-0.5*e13*e222-0.5*e13*e282-e23*e27*e17-e23*e28*e18+e26*e25*e18+e26*e24*e17+e26*e14*e27-e23*e21*e11-e23*e22*e12+e26*e15*e28+e23*e25*e15+e23*e24*e14+e16*e23*e26+e16*e24*e27+e16*e25*e28+0.5*e13*e262+e20*e21*e14+e20*e22*e15+e20*e12*e25+0.5*e13*e242+0.5*e13*e252+0.5*e202*e13+1.5*e13*e232+e10*e20*e23+e10*e22*e25+e10*e21*e24; +A[1 + 10*9]=0.5*e202*e23+e20*e22*e25+e20*e21*e24+0.5*e233+0.5*e23*e242+0.5*e23*e252+0.5*e23*e262+e26*e24*e27+e26*e25*e28-0.5*e23*e212-0.5*e23*e272-0.5*e23*e222-0.5*e23*e282; +A[1 + 10*10]=e00*e30*e03+0.5*e33*e062-0.5*e33*e012-0.5*e33*e022-0.5*e33*e072+e03*e35*e05+e06*e03*e36+e06*e34*e07+e06*e04*e37+e06*e35*e08+e06*e05*e38+e36*e04*e07+e36*e05*e08-e03*e32*e02-e03*e31*e01-e03*e37*e07+e00*e31*e04+e00*e01*e34+e00*e32*e05+e00*e02*e35+e30*e01*e04+e30*e02*e05+e03*e34*e04-e03*e38*e08+0.5*e002*e33+1.5*e33*e032+0.5*e33*e042+0.5*e33*e052-0.5*e33*e082; +A[1 + 10*11]=e06*e35*e18+e06*e33*e16+e00*e30*e13+e00*e10*e33+e00*e31*e14+e00*e11*e34+e00*e32*e15+e00*e12*e35+e10*e30*e03-e33*e17*e07-e33*e18*e08+e10*e31*e04+e10*e01*e34+e10*e32*e05+e10*e02*e35+e30*e11*e04+e30*e01*e14+e30*e12*e05+e30*e02*e15+3*e03*e33*e13+e03*e35*e15+e03*e34*e14+e13*e34*e04+e13*e35*e05+e33*e14*e04+e33*e15*e05+e06*e13*e36+e06*e15*e38+e06*e34*e17+e06*e14*e37+e16*e03*e36+e16*e34*e07+e16*e04*e37+e16*e35*e08+e16*e05*e38+e36*e14*e07+e36*e04*e17+e36*e15*e08+e36*e05*e18-e03*e31*e11-e03*e32*e12-e03*e37*e17-e03*e38*e18-e13*e32*e02-e13*e31*e01-e13*e37*e07-e13*e38*e08-e33*e12*e02-e33*e11*e01; +A[1 + 10*12]=e16*e13*e36+e10*e11*e34+0.5*e33*e152+0.5*e33*e142+0.5*e33*e162-0.5*e33*e112-0.5*e33*e122-0.5*e33*e172-0.5*e33*e182+0.5*e102*e33+1.5*e33*e132+e10*e30*e13+e10*e31*e14+e10*e32*e15+e10*e12*e35+e30*e11*e14+e30*e12*e15+e13*e35*e15+e13*e34*e14+e16*e35*e18+e16*e15*e38+e16*e34*e17+e16*e14*e37+e36*e15*e18+e36*e14*e17-e13*e31*e11-e13*e32*e12-e13*e37*e17-e13*e38*e18; +A[1 + 10*13]=e06*e35*e28+e36*e04*e27+e00*e20*e33+e00*e30*e23+3*e03*e33*e23+e03*e34*e24+e03*e35*e25+e23*e34*e04+e23*e35*e05+e33*e24*e04+e33*e25*e05+e06*e33*e26+e06*e23*e36+e06*e34*e27+e06*e24*e37+e06*e25*e38+e26*e03*e36+e26*e34*e07+e26*e04*e37+e26*e35*e08+e26*e05*e38+e36*e24*e07+e36*e25*e08+e36*e05*e28-e03*e31*e21-e03*e37*e27-e03*e32*e22-e03*e38*e28-e23*e32*e02-e23*e31*e01-e23*e37*e07-e23*e38*e08-e33*e22*e02-e33*e21*e01-e33*e27*e07-e33*e28*e08+e00*e32*e25+e00*e22*e35+e00*e31*e24+e00*e21*e34+e20*e30*e03+e20*e31*e04+e20*e01*e34+e20*e32*e05+e20*e02*e35+e30*e21*e04+e30*e01*e24+e30*e22*e05+e30*e02*e25; +A[1 + 10*14]=e10*e30*e23+e10*e20*e33+e10*e22*e35+e10*e32*e25+e10*e31*e24+e10*e21*e34+e20*e30*e13+e20*e31*e14+e20*e11*e34+e20*e32*e15+e20*e12*e35+e30*e21*e14+e30*e11*e24+e30*e22*e15+e30*e12*e25+3*e13*e33*e23+e13*e34*e24+e13*e35*e25+e23*e35*e15+e23*e34*e14+e33*e25*e15+e33*e24*e14+e16*e33*e26+e16*e23*e36+e16*e34*e27+e16*e24*e37+e16*e35*e28+e16*e25*e38+e26*e13*e36+e26*e35*e18+e26*e15*e38+e26*e34*e17+e26*e14*e37+e36*e25*e18+e36*e15*e28+e36*e24*e17+e36*e14*e27-e13*e31*e21-e13*e37*e27-e13*e32*e22-e13*e38*e28-e23*e31*e11-e23*e32*e12-e23*e37*e17-e23*e38*e18-e33*e21*e11-e33*e22*e12-e33*e27*e17-e33*e28*e18; +A[1 + 10*15]=-0.5*e33*e212-0.5*e33*e272-0.5*e33*e222-0.5*e33*e282+e26*e23*e36+e20*e30*e23+e20*e32*e25+e20*e22*e35+e20*e31*e24+e20*e21*e34+e30*e22*e25+e30*e21*e24+e23*e34*e24+e23*e35*e25+e26*e34*e27+e26*e24*e37+e26*e35*e28+e26*e25*e38+e36*e24*e27+e36*e25*e28-e23*e31*e21-e23*e37*e27-e23*e32*e22-e23*e38*e28+0.5*e202*e33+1.5*e33*e232+0.5*e33*e242+0.5*e33*e252+0.5*e33*e262; +A[1 + 10*16]=e33*e35*e05+e30*e32*e05+0.5*e03*e362+0.5*e302*e03+1.5*e03*e332+0.5*e03*e352+0.5*e03*e342+e00*e30*e33+e00*e31*e34+e00*e32*e35+e30*e31*e04+e30*e01*e34+e30*e02*e35+e33*e34*e04+e06*e33*e36+e06*e35*e38+e06*e34*e37+e36*e34*e07+e36*e04*e37+e36*e35*e08+e36*e05*e38-e33*e32*e02-e33*e31*e01-e33*e37*e07-e33*e38*e08-0.5*e03*e322-0.5*e03*e382-0.5*e03*e312-0.5*e03*e372; +A[1 + 10*17]=-e33*e31*e11-e33*e32*e12-e33*e38*e18+e30*e11*e34+e30*e32*e15+e30*e12*e35+e33*e35*e15+e33*e34*e14+e16*e33*e36+e16*e35*e38+e16*e34*e37+e36*e35*e18+e36*e15*e38+e36*e34*e17+e36*e14*e37-e33*e37*e17+0.5*e302*e13+1.5*e13*e332+0.5*e13*e352+0.5*e13*e342+0.5*e13*e362-0.5*e13*e322-0.5*e13*e382-0.5*e13*e312-0.5*e13*e372+e10*e30*e33+e10*e31*e34+e10*e32*e35+e30*e31*e14; +A[1 + 10*18]=e36*e25*e38+0.5*e302*e23+1.5*e23*e332+0.5*e23*e352+0.5*e23*e342+0.5*e23*e362-0.5*e23*e322-0.5*e23*e382-0.5*e23*e312-0.5*e23*e372+e20*e30*e33+e20*e31*e34+e20*e32*e35+e30*e32*e25+e30*e22*e35+e30*e31*e24+e30*e21*e34+e33*e34*e24+e33*e35*e25+e26*e33*e36+e26*e35*e38+e26*e34*e37+e36*e34*e27+e36*e24*e37+e36*e35*e28-e33*e31*e21-e33*e37*e27-e33*e32*e22-e33*e38*e28; +A[1 + 10*19]=0.5*e302*e33+e30*e31*e34+e30*e32*e35+0.5*e333+0.5*e33*e352+0.5*e33*e342+0.5*e33*e362+e36*e35*e38+e36*e34*e37-0.5*e33*e322-0.5*e33*e382-0.5*e33*e312-0.5*e33*e372; +A[2 + 10*0]=0.5*e002*e06+e00*e01*e07+e00*e02*e08+0.5*e032*e06+e03*e04*e07+e03*e05*e08+0.5*e063+0.5*e06*e072+0.5*e06*e082-0.5*e06*e012-0.5*e06*e022-0.5*e06*e042-0.5*e06*e052; +A[2 + 10*1]=e00*e10*e06+0.5*e002*e16+0.5*e032*e16+1.5*e16*e062+0.5*e16*e072+0.5*e16*e082-0.5*e16*e012-0.5*e16*e022-0.5*e16*e042-0.5*e16*e052+e00*e11*e07+e00*e01*e17+e00*e12*e08+e00*e02*e18+e10*e01*e07+e10*e02*e08+e03*e13*e06+e03*e14*e07+e03*e04*e17+e03*e15*e08+e03*e05*e18+e13*e04*e07+e13*e05*e08+e06*e17*e07+e06*e18*e08-e06*e12*e02-e06*e11*e01-e06*e14*e04-e06*e15*e05; +A[2 + 10*2]=e13*e14*e07+0.5*e102*e06+e00*e10*e16+e00*e12*e18+e00*e11*e17+e10*e11*e07+e10*e01*e17+e10*e12*e08+e10*e02*e18+e03*e13*e16+e03*e15*e18+e03*e14*e17+e13*e04*e17+e13*e15*e08+e13*e05*e18+e16*e17*e07+e16*e18*e08-e16*e12*e02-e16*e11*e01-e16*e14*e04-e16*e15*e05+0.5*e132*e06+1.5*e06*e162+0.5*e06*e182+0.5*e06*e172-0.5*e06*e112-0.5*e06*e122-0.5*e06*e142-0.5*e06*e152; +A[2 + 10*3]=0.5*e102*e16+e10*e12*e18+e10*e11*e17+0.5*e132*e16+e13*e15*e18+e13*e14*e17+0.5*e163+0.5*e16*e182+0.5*e16*e172-0.5*e16*e112-0.5*e16*e122-0.5*e16*e142-0.5*e16*e152; +A[2 + 10*4]=e06*e27*e07+e23*e05*e08+e23*e04*e07+e03*e05*e28+e03*e25*e08+e03*e04*e27+e03*e24*e07+e20*e02*e08+e20*e01*e07+e00*e02*e28+e00*e22*e08+e00*e01*e27+e00*e21*e07+e00*e20*e06-e06*e25*e05-e06*e24*e04-e06*e21*e01-e06*e22*e02+e06*e28*e08-0.5*e26*e042-0.5*e26*e052-0.5*e26*e012-0.5*e26*e022+0.5*e26*e082+0.5*e26*e072+1.5*e26*e062+0.5*e002*e26+e03*e23*e06+0.5*e032*e26; +A[2 + 10*5]=e13*e05*e28+e00*e12*e28+e13*e25*e08+e13*e04*e27+e13*e24*e07+e13*e23*e06+e03*e14*e27+e03*e24*e17+e03*e15*e28+e03*e25*e18+e03*e13*e26+e03*e23*e16+e20*e02*e18+e20*e12*e08+e20*e01*e17+e20*e11*e07+e00*e21*e17+e10*e02*e28+e10*e22*e08+e10*e01*e27+e10*e21*e07+e10*e20*e06+e00*e11*e27-e26*e15*e05-e26*e14*e04-e26*e11*e01-e26*e12*e02-e16*e25*e05-e16*e24*e04-e16*e21*e01-e16*e22*e02-e06*e24*e14-e06*e22*e12-e06*e21*e11-e06*e25*e15+e00*e20*e16+e00*e22*e18+e00*e10*e26+e26*e18*e08+e26*e17*e07+e16*e28*e08+e16*e27*e07+e06*e27*e17+e06*e28*e18+3*e06*e26*e16+e23*e05*e18+e23*e15*e08+e23*e04*e17+e23*e14*e07; +A[2 + 10*6]=e10*e22*e18+0.5*e26*e182+0.5*e26*e172+e16*e28*e18+e16*e27*e17-e16*e25*e15-e16*e21*e11-e16*e22*e12+1.5*e26*e162+e13*e15*e28+e13*e24*e17+e13*e14*e27+e23*e15*e18+e23*e14*e17+e10*e12*e28+e10*e21*e17+e10*e11*e27+e20*e12*e18+e20*e11*e17+e13*e23*e16+e13*e25*e18+e10*e20*e16+0.5*e102*e26-0.5*e26*e122-0.5*e26*e142-0.5*e26*e152-e16*e24*e14-0.5*e26*e112+0.5*e132*e26; +A[2 + 10*7]=-0.5*e06*e212-0.5*e06*e252-0.5*e06*e242+0.5*e06*e272+0.5*e06*e282-0.5*e06*e222+e20*e02*e28+e03*e23*e26+e03*e24*e27+e03*e25*e28+e23*e24*e07+e23*e04*e27+e23*e25*e08+e23*e05*e28+e26*e28*e08-e26*e22*e02-e26*e21*e01-e26*e24*e04-e26*e25*e05+e26*e27*e07+e00*e20*e26+e00*e21*e27+e00*e22*e28+e20*e21*e07+e20*e01*e27+e20*e22*e08+0.5*e202*e06+0.5*e232*e06+1.5*e06*e262; +A[2 + 10*8]=-e26*e24*e14-0.5*e16*e212-0.5*e16*e252-0.5*e16*e242-e26*e25*e15-0.5*e16*e222-e26*e21*e11+e26*e28*e18+e26*e27*e17-e26*e22*e12+e23*e15*e28+e23*e24*e17+e23*e14*e27+0.5*e232*e16+1.5*e16*e262+0.5*e16*e272+0.5*e16*e282+e10*e20*e26+e10*e21*e27+e10*e22*e28+e20*e22*e18+e20*e12*e28+e20*e21*e17+e20*e11*e27+e13*e23*e26+e13*e24*e27+e13*e25*e28+e23*e25*e18+0.5*e202*e16; +A[2 + 10*9]=0.5*e202*e26+e20*e21*e27+e20*e22*e28+0.5*e232*e26+e23*e24*e27+e23*e25*e28+0.5*e263+0.5*e26*e272+0.5*e26*e282-0.5*e26*e222-0.5*e26*e212-0.5*e26*e252-0.5*e26*e242; +A[2 + 10*10]=e03*e34*e07+0.5*e032*e36+1.5*e36*e062+e03*e33*e06+e00*e31*e07+e00*e01*e37+e00*e32*e08+e00*e02*e38+e30*e01*e07+e30*e02*e08+e03*e04*e37+e03*e35*e08+e03*e05*e38+0.5*e002*e36-0.5*e36*e022-0.5*e36*e042-0.5*e36*e052+0.5*e36*e072+0.5*e36*e082-0.5*e36*e012+e33*e04*e07+e33*e05*e08+e06*e37*e07+e06*e38*e08-e06*e32*e02-e06*e31*e01-e06*e34*e04-e06*e35*e05+e00*e30*e06; +A[2 + 10*11]=e13*e33*e06+e13*e34*e07+e13*e04*e37+e13*e35*e08+e13*e05*e38+e33*e14*e07+e33*e04*e17+e33*e15*e08+e33*e05*e18+3*e06*e36*e16+e06*e38*e18+e06*e37*e17+e16*e37*e07+e16*e38*e08+e36*e17*e07+e36*e18*e08-e06*e35*e15-e06*e31*e11-e06*e32*e12+e00*e31*e17+e00*e11*e37+e10*e30*e06+e10*e31*e07+e10*e01*e37+e10*e32*e08+e10*e02*e38+e30*e11*e07+e30*e01*e17+e30*e12*e08+e30*e02*e18+e03*e33*e16+e03*e13*e36+e03*e35*e18+e03*e15*e38+e03*e34*e17+e03*e14*e37+e00*e30*e16+e00*e12*e38-e06*e34*e14-e16*e32*e02-e16*e31*e01-e16*e34*e04-e16*e35*e05-e36*e12*e02-e36*e11*e01-e36*e14*e04-e36*e15*e05+e00*e10*e36+e00*e32*e18; +A[2 + 10*12]=0.5*e36*e182+0.5*e36*e172-0.5*e36*e112-0.5*e36*e122-0.5*e36*e142-0.5*e36*e152+0.5*e102*e36+0.5*e132*e36+1.5*e36*e162+e10*e30*e16+e10*e32*e18+e10*e12*e38+e10*e31*e17+e10*e11*e37+e30*e12*e18+e30*e11*e17+e13*e33*e16+e13*e35*e18+e13*e15*e38+e13*e34*e17+e13*e14*e37+e33*e15*e18+e33*e14*e17+e16*e38*e18+e16*e37*e17-e16*e35*e15-e16*e31*e11-e16*e32*e12-e16*e34*e14; +A[2 + 10*13]=e00*e20*e36+e00*e31*e27+e00*e21*e37+e00*e32*e28+e00*e22*e38+e20*e30*e06+e20*e31*e07+e20*e01*e37+e20*e32*e08+e20*e02*e38+e30*e21*e07+e30*e01*e27+e30*e22*e08+e30*e02*e28+e03*e33*e26+e03*e23*e36+e03*e34*e27+e03*e24*e37+e03*e35*e28-e26*e31*e01-e26*e35*e05-e36*e22*e02-e36*e21*e01-e36*e24*e04-e36*e25*e05-e26*e34*e04+e03*e25*e38+e23*e34*e07+e23*e04*e37+e23*e35*e08+e23*e05*e38+e33*e24*e07+e33*e04*e27+e33*e25*e08+e33*e05*e28+3*e06*e36*e26+e06*e37*e27+e06*e38*e28+e26*e37*e07+e26*e38*e08+e36*e27*e07+e36*e28*e08-e06*e32*e22-e06*e31*e21-e06*e35*e25-e06*e34*e24-e26*e32*e02+e00*e30*e26+e23*e33*e06; +A[2 + 10*14]=e10*e30*e26+e10*e20*e36+e10*e31*e27+e10*e21*e37+e10*e32*e28+e10*e22*e38+e20*e30*e16+e20*e32*e18+e20*e12*e38+e20*e31*e17+e20*e11*e37+e30*e22*e18+e30*e12*e28+e30*e21*e17+e30*e11*e27+e13*e33*e26+e13*e23*e36+e13*e34*e27+e13*e24*e37+e13*e35*e28+e13*e25*e38+e23*e33*e16+e23*e35*e18+e23*e15*e38+e23*e34*e17+e23*e14*e37+e33*e25*e18+e33*e15*e28+e33*e24*e17+e33*e14*e27+3*e16*e36*e26+e16*e37*e27+e16*e38*e28+e26*e38*e18+e26*e37*e17+e36*e28*e18+e36*e27*e17-e16*e32*e22-e16*e31*e21-e16*e35*e25-e16*e34*e24-e26*e35*e15-e26*e31*e11-e26*e32*e12-e26*e34*e14-e36*e25*e15-e36*e21*e11-e36*e22*e12-e36*e24*e14; +A[2 + 10*15]=e33*e25*e28+e20*e30*e26+e20*e32*e28+e20*e31*e27+e20*e21*e37+e20*e22*e38+e30*e21*e27+e30*e22*e28+e23*e33*e26+e23*e34*e27+e23*e24*e37+e23*e35*e28+e23*e25*e38+e33*e24*e27+e26*e37*e27+e26*e38*e28-e26*e32*e22-e26*e31*e21-e26*e35*e25-e26*e34*e24+0.5*e202*e36+0.5*e232*e36+1.5*e36*e262+0.5*e36*e272+0.5*e36*e282-0.5*e36*e222-0.5*e36*e212-0.5*e36*e252-0.5*e36*e242; +A[2 + 10*16]=e00*e30*e36+e00*e32*e38+e00*e31*e37+e30*e31*e07+e30*e01*e37+e30*e32*e08+e30*e02*e38+e03*e33*e36-0.5*e06*e342+e03*e35*e38+e33*e34*e07+e33*e04*e37+e33*e35*e08+e33*e05*e38+e36*e37*e07+e36*e38*e08-e36*e32*e02-e36*e31*e01-e36*e34*e04-e36*e35*e05+e03*e34*e37+0.5*e302*e06+0.5*e332*e06+1.5*e06*e362+0.5*e06*e382+0.5*e06*e372-0.5*e06*e352-0.5*e06*e312-0.5*e06*e322; +A[2 + 10*17]=-e36*e35*e15+e10*e30*e36+0.5*e302*e16+0.5*e332*e16+1.5*e16*e362+0.5*e16*e382+0.5*e16*e372-0.5*e16*e352-0.5*e16*e312-0.5*e16*e322-0.5*e16*e342+e10*e32*e38+e10*e31*e37+e30*e32*e18+e30*e12*e38+e30*e31*e17+e30*e11*e37+e13*e33*e36+e13*e35*e38+e13*e34*e37+e33*e35*e18+e33*e15*e38+e33*e34*e17+e33*e14*e37+e36*e38*e18+e36*e37*e17-e36*e31*e11-e36*e32*e12-e36*e34*e14; +A[2 + 10*18]=-e36*e35*e25+e30*e32*e28+0.5*e302*e26+0.5*e332*e26+1.5*e26*e362+0.5*e26*e382+0.5*e26*e372-0.5*e26*e352-0.5*e26*e312-0.5*e26*e322-0.5*e26*e342+e20*e30*e36+e20*e32*e38+e20*e31*e37+e30*e31*e27+e30*e21*e37+e30*e22*e38+e23*e33*e36+e23*e35*e38+e23*e34*e37+e33*e34*e27+e33*e24*e37+e33*e35*e28+e33*e25*e38+e36*e37*e27+e36*e38*e28-e36*e32*e22-e36*e31*e21-e36*e34*e24; +A[2 + 10*19]=0.5*e302*e36+e30*e32*e38+e30*e31*e37+0.5*e332*e36+e33*e35*e38+e33*e34*e37+0.5*e363+0.5*e36*e382+0.5*e36*e372-0.5*e36*e352-0.5*e36*e312-0.5*e36*e322-0.5*e36*e342; +A[3 + 10*0]=0.5*e01*e002+0.5*e013+0.5*e01*e022+e04*e00*e03+0.5*e01*e042+e04*e02*e05+e07*e00*e06+0.5*e01*e072+e07*e02*e08-0.5*e01*e032-0.5*e01*e052-0.5*e01*e062-0.5*e01*e082; +A[3 + 10*1]=1.5*e11*e012+0.5*e11*e002+0.5*e11*e022+0.5*e11*e042+0.5*e11*e072-0.5*e11*e032-0.5*e11*e052-0.5*e11*e062-0.5*e11*e082+e01*e10*e00+e01*e12*e02+e04*e10*e03+e04*e00*e13+e04*e01*e14+e04*e12*e05+e04*e02*e15+e14*e00*e03+e14*e02*e05+e07*e10*e06+e07*e00*e16+e07*e01*e17+e07*e12*e08+e07*e02*e18+e17*e00*e06+e17*e02*e08-e01*e13*e03-e01*e16*e06-e01*e15*e05-e01*e18*e08; +A[3 + 10*2]=e17*e02*e18+e14*e10*e03+e11*e12*e02-e11*e18*e08+0.5*e01*e102+0.5*e01*e122+1.5*e01*e112+0.5*e01*e142+0.5*e01*e172-0.5*e01*e132-0.5*e01*e152-0.5*e01*e162-0.5*e01*e182+e11*e10*e00+e04*e10*e13+e04*e12*e15+e04*e11*e14+e14*e00*e13+e14*e12*e05+e14*e02*e15+e07*e10*e16+e07*e12*e18+e07*e11*e17+e17*e10*e06+e17*e00*e16+e17*e12*e08-e11*e13*e03-e11*e16*e06-e11*e15*e05; +A[3 + 10*3]=0.5*e11*e102+0.5*e11*e122+0.5*e113+e14*e10*e13+e14*e12*e15+0.5*e11*e142+e17*e10*e16+e17*e12*e18+0.5*e11*e172-0.5*e11*e132-0.5*e11*e152-0.5*e11*e162-0.5*e11*e182; +A[3 + 10*4]=-e01*e25*e05-e01*e26*e06-e01*e23*e03+e27*e02*e08+e27*e00*e06+e07*e02*e28+e07*e22*e08+e07*e01*e27+e07*e00*e26+e24*e02*e05+e24*e00*e03+e04*e02*e25+e04*e22*e05+e04*e01*e24+e04*e00*e23+e04*e20*e03+e01*e22*e02+e01*e20*e00-e01*e28*e08+e07*e20*e06+0.5*e21*e072+0.5*e21*e042+0.5*e21*e022+0.5*e21*e002+1.5*e21*e012-0.5*e21*e082-0.5*e21*e052-0.5*e21*e062-0.5*e21*e032; +A[3 + 10*5]=e11*e20*e00+e07*e20*e16+3*e01*e21*e11+e01*e22*e12-e21*e18*e08-e21*e15*e05-e21*e16*e06-e21*e13*e03-e11*e28*e08-e11*e25*e05-e11*e26*e06-e11*e23*e03-e01*e28*e18-e01*e23*e13-e01*e25*e15-e01*e26*e16+e27*e02*e18+e27*e12*e08+e27*e00*e16+e27*e10*e06+e17*e02*e28+e17*e22*e08+e17*e01*e27+e17*e00*e26+e17*e20*e06+e07*e11*e27+e07*e21*e17+e07*e12*e28+e07*e22*e18+e07*e10*e26+e24*e02*e15+e24*e12*e05+e24*e00*e13+e24*e10*e03+e14*e02*e25+e14*e22*e05+e14*e01*e24+e14*e00*e23+e14*e20*e03+e04*e11*e24+e04*e21*e14+e04*e12*e25+e04*e22*e15+e21*e12*e02+e04*e20*e13+e01*e20*e10+e11*e22*e02+e21*e10*e00+e04*e10*e23; +A[3 + 10*6]=1.5*e21*e112+0.5*e21*e102+0.5*e21*e122+e11*e20*e10+e11*e22*e12+e14*e10*e23+e14*e22*e15+e14*e12*e25-0.5*e21*e162-0.5*e21*e152-0.5*e21*e132-0.5*e21*e182+e27*e12*e18-e11*e26*e16-e11*e25*e15-e11*e23*e13-e11*e28*e18+e17*e20*e16+e17*e10*e26+e17*e22*e18+e17*e12*e28+e17*e11*e27+e27*e10*e16+0.5*e21*e172+e14*e11*e24+e24*e10*e13+e24*e12*e15+0.5*e21*e142+e14*e20*e13; +A[3 + 10*7]=-0.5*e01*e262-0.5*e01*e282-0.5*e01*e252-0.5*e01*e232+0.5*e01*e272+e27*e22*e08+e27*e02*e28-e21*e23*e03-e21*e26*e06-e21*e25*e05-e21*e28*e08+e04*e22*e25+e24*e20*e03+e24*e00*e23+e24*e22*e05+e24*e02*e25+e07*e20*e26+e07*e21*e27+e07*e22*e28+e27*e20*e06+e27*e00*e26+e21*e20*e00+e21*e22*e02+e04*e20*e23+e04*e21*e24+0.5*e01*e222+0.5*e01*e242+1.5*e01*e212+0.5*e01*e202; +A[3 + 10*8]=-0.5*e11*e282-0.5*e11*e252-e21*e26*e16+e27*e12*e28-e21*e25*e15-e21*e23*e13-e21*e28*e18+e17*e20*e26+e17*e21*e27+e17*e22*e28+e27*e20*e16+e27*e10*e26+e27*e22*e18+0.5*e11*e242+0.5*e11*e272-0.5*e11*e232-0.5*e11*e262+0.5*e11*e202+1.5*e11*e212+0.5*e11*e222+e21*e20*e10+e14*e20*e23+e14*e21*e24+e14*e22*e25+e24*e20*e13+e24*e10*e23+e24*e22*e15+e24*e12*e25+e21*e22*e12; +A[3 + 10*9]=0.5*e21*e202+0.5*e213+0.5*e21*e222+e24*e20*e23+0.5*e21*e242+e24*e22*e25+e27*e20*e26+0.5*e21*e272+e27*e22*e28-0.5*e21*e232-0.5*e21*e262-0.5*e21*e282-0.5*e21*e252; +A[3 + 10*10]=-0.5*e31*e032-0.5*e31*e052-0.5*e31*e062-0.5*e31*e082+e07*e30*e06+e07*e00*e36+e07*e01*e37+e07*e32*e08+e07*e02*e38+e37*e00*e06+e37*e02*e08-e01*e33*e03-e01*e36*e06-e01*e35*e05-e01*e38*e08+0.5*e31*e072+e04*e30*e03+e04*e00*e33+e04*e01*e34+e04*e32*e05+e04*e02*e35+e34*e00*e03+e34*e02*e05+0.5*e31*e002+0.5*e31*e022+0.5*e31*e042+e01*e30*e00+e01*e32*e02+1.5*e31*e012; +A[3 + 10*11]=e34*e12*e05+e34*e02*e15+e07*e10*e36+e07*e32*e18+e07*e12*e38+e07*e31*e17+e07*e11*e37+e17*e30*e06+e17*e00*e36+e17*e01*e37+e17*e32*e08+e17*e02*e38+e37*e10*e06+e37*e00*e16+e37*e12*e08+e37*e02*e18-e01*e36*e16-e01*e35*e15-e01*e33*e13-e01*e38*e18-e11*e33*e03-e11*e36*e06-e11*e35*e05+e01*e30*e10+e01*e32*e12+3*e01*e31*e11+e11*e30*e00+e11*e32*e02+e31*e10*e00+e31*e12*e02+e04*e30*e13+e04*e10*e33+e04*e32*e15+e04*e12*e35+e04*e31*e14+e04*e11*e34+e14*e30*e03+e14*e00*e33+e14*e01*e34+e14*e32*e05+e14*e02*e35+e34*e10*e03+e34*e00*e13+e07*e30*e16-e11*e38*e08-e31*e13*e03-e31*e16*e06-e31*e15*e05-e31*e18*e08; +A[3 + 10*12]=-e11*e33*e13-e11*e38*e18+0.5*e31*e142+0.5*e31*e172-0.5*e31*e162-0.5*e31*e152-0.5*e31*e132-0.5*e31*e182+0.5*e31*e122+0.5*e31*e102+e11*e30*e10+e11*e32*e12+e14*e30*e13+e14*e10*e33+e14*e32*e15+e14*e12*e35+e14*e11*e34+e34*e10*e13+e34*e12*e15+e17*e30*e16+e17*e10*e36+e17*e32*e18+e17*e12*e38+e17*e11*e37+e37*e10*e16+e37*e12*e18-e11*e36*e16-e11*e35*e15+1.5*e31*e112; +A[3 + 10*13]=-e21*e35*e05+e07*e32*e28+e01*e30*e20-e21*e33*e03-e21*e36*e06-e21*e38*e08-e31*e23*e03-e31*e26*e06-e31*e25*e05-e31*e28*e08+3*e01*e31*e21+e01*e32*e22+e21*e30*e00+e21*e32*e02+e31*e20*e00+e31*e22*e02+e04*e30*e23+e04*e20*e33+e04*e31*e24+e04*e21*e34+e04*e32*e25+e04*e22*e35+e24*e30*e03+e24*e00*e33+e24*e01*e34+e24*e32*e05+e24*e02*e35+e34*e20*e03+e34*e00*e23+e34*e22*e05+e34*e02*e25+e07*e30*e26+e07*e20*e36+e07*e31*e27+e07*e21*e37+e07*e22*e38+e27*e30*e06+e27*e00*e36+e27*e01*e37+e27*e32*e08+e27*e02*e38+e37*e00*e26+e37*e22*e08+e37*e02*e28-e01*e33*e23-e01*e36*e26-e01*e38*e28-e01*e35*e25+e37*e20*e06; +A[3 + 10*14]=e11*e32*e22+e34*e12*e25+e11*e30*e20+3*e11*e31*e21+e21*e30*e10+e21*e32*e12+e34*e10*e23+e34*e22*e15+e17*e30*e26+e17*e20*e36+e17*e31*e27+e17*e21*e37+e17*e32*e28+e17*e22*e38+e27*e30*e16+e27*e10*e36+e27*e32*e18+e27*e12*e38+e27*e11*e37+e37*e20*e16+e37*e10*e26+e37*e22*e18+e37*e12*e28-e11*e33*e23-e11*e36*e26-e11*e38*e28-e11*e35*e25-e21*e36*e16-e21*e35*e15-e21*e33*e13-e21*e38*e18-e31*e26*e16-e31*e25*e15-e31*e23*e13-e31*e28*e18+e31*e20*e10+e31*e22*e12+e14*e30*e23+e14*e20*e33+e14*e31*e24+e14*e21*e34+e14*e32*e25+e14*e22*e35+e24*e30*e13+e24*e10*e33+e24*e32*e15+e24*e12*e35+e24*e11*e34+e34*e20*e13; +A[3 + 10*15]=-e21*e36*e26+e37*e22*e28-e21*e33*e23-e21*e38*e28-e21*e35*e25+0.5*e31*e222+0.5*e31*e242+0.5*e31*e272-0.5*e31*e232-0.5*e31*e262-0.5*e31*e282-0.5*e31*e252+e21*e30*e20+e21*e32*e22+e24*e30*e23+e24*e20*e33+e24*e21*e34+e24*e32*e25+e24*e22*e35+e34*e20*e23+e34*e22*e25+e27*e30*e26+e27*e20*e36+e27*e21*e37+e27*e32*e28+e27*e22*e38+e37*e20*e26+1.5*e31*e212+0.5*e31*e202; +A[3 + 10*16]=e04*e32*e35+0.5*e01*e372-0.5*e01*e352-0.5*e01*e362-0.5*e01*e332-0.5*e01*e382+e04*e31*e34+e34*e30*e03+e34*e00*e33+e34*e32*e05+e34*e02*e35+e07*e30*e36+e07*e32*e38+e07*e31*e37+e37*e30*e06+e37*e00*e36+e37*e32*e08+e04*e30*e33+e37*e02*e38-e31*e33*e03-e31*e36*e06-e31*e35*e05-e31*e38*e08+0.5*e01*e302+0.5*e01*e322+1.5*e01*e312+0.5*e01*e342+e31*e30*e00+e31*e32*e02; +A[3 + 10*17]=e31*e32*e12+e14*e30*e33+e14*e32*e35+e14*e31*e34+e34*e30*e13+e34*e10*e33+e34*e32*e15+e34*e12*e35+e17*e30*e36+e17*e32*e38+e17*e31*e37+e37*e30*e16+e37*e10*e36+e37*e32*e18+e37*e12*e38-e31*e36*e16-e31*e35*e15+0.5*e11*e302+0.5*e11*e322+1.5*e11*e312-e31*e33*e13-e31*e38*e18+0.5*e11*e342+0.5*e11*e372+e31*e30*e10-0.5*e11*e352-0.5*e11*e362-0.5*e11*e332-0.5*e11*e382; +A[3 + 10*18]=e34*e32*e25+0.5*e21*e342+0.5*e21*e372-0.5*e21*e352-0.5*e21*e362-0.5*e21*e332-0.5*e21*e382+0.5*e21*e302+0.5*e21*e322+1.5*e21*e312+e31*e30*e20+e31*e32*e22+e24*e30*e33+e24*e32*e35+e24*e31*e34+e34*e30*e23+e34*e20*e33+e34*e22*e35+e27*e30*e36+e27*e32*e38+e27*e31*e37+e37*e30*e26+e37*e20*e36+e37*e32*e28+e37*e22*e38-e31*e33*e23-e31*e36*e26-e31*e38*e28-e31*e35*e25; +A[3 + 10*19]=0.5*e31*e302+0.5*e31*e322+0.5*e313+e34*e30*e33+e34*e32*e35+0.5*e31*e342+e37*e30*e36+e37*e32*e38+0.5*e31*e372-0.5*e31*e352-0.5*e31*e362-0.5*e31*e332-0.5*e31*e382; +A[4 + 10*0]=e01*e00*e03+0.5*e012*e04+e01*e02*e05+0.5*e04*e032+0.5*e043+0.5*e04*e052+e07*e03*e06+0.5*e04*e072+e07*e05*e08-0.5*e04*e002-0.5*e04*e022-0.5*e04*e062-0.5*e04*e082; +A[4 + 10*1]=e07*e13*e06+e01*e10*e03-0.5*e14*e002-0.5*e14*e022-0.5*e14*e062-0.5*e14*e082+e01*e00*e13+e01*e11*e04+e01*e12*e05+e01*e02*e15+e11*e00*e03+e11*e02*e05+e04*e13*e03+e04*e15*e05+e07*e03*e16+e07*e04*e17+e07*e15*e08+e07*e05*e18+e17*e03*e06+e17*e05*e08-e04*e10*e00-e04*e12*e02-e04*e16*e06-e04*e18*e08+0.5*e012*e14+1.5*e14*e042+0.5*e14*e032+0.5*e14*e052+0.5*e14*e072; +A[4 + 10*2]=e11*e10*e03+0.5*e112*e04+0.5*e04*e132+0.5*e04*e152+1.5*e04*e142+0.5*e04*e172-0.5*e04*e102-0.5*e04*e162-0.5*e04*e122-0.5*e04*e182+e01*e10*e13+e01*e12*e15+e01*e11*e14+e11*e00*e13+e11*e12*e05+e11*e02*e15+e14*e13*e03+e14*e15*e05+e07*e13*e16+e07*e15*e18+e07*e14*e17+e17*e13*e06+e17*e03*e16+e17*e15*e08+e17*e05*e18-e14*e10*e00-e14*e12*e02-e14*e16*e06-e14*e18*e08; +A[4 + 10*3]=e11*e10*e13+e11*e12*e15+0.5*e112*e14+0.5*e14*e132+0.5*e14*e152+0.5*e143+e17*e13*e16+e17*e15*e18+0.5*e14*e172-0.5*e14*e102-0.5*e14*e162-0.5*e14*e122-0.5*e14*e182; +A[4 + 10*4]=-e04*e28*e08-e04*e26*e06-e04*e22*e02-e04*e20*e00+e27*e05*e08+e27*e03*e06+e07*e05*e28+e07*e25*e08+e07*e04*e27+e07*e03*e26+e07*e23*e06+e04*e25*e05+e04*e23*e03+e21*e02*e05+e21*e00*e03+e01*e02*e25+e01*e22*e05+e01*e21*e04+e01*e00*e23+e01*e20*e03+0.5*e012*e24+0.5*e24*e072+0.5*e24*e052+0.5*e24*e032+1.5*e24*e042-0.5*e24*e022-0.5*e24*e002-0.5*e24*e082-0.5*e24*e062; +A[4 + 10*5]=e11*e02*e25+e11*e22*e05+e11*e21*e04-e24*e18*e08-e24*e16*e06-e24*e12*e02-e14*e28*e08-e14*e26*e06-e14*e22*e02-e14*e20*e00-e04*e28*e18-e04*e22*e12-e04*e26*e16-e04*e20*e10+e27*e05*e18+e27*e15*e08+e27*e03*e16+e27*e13*e06+e17*e05*e28+e17*e25*e08+e17*e04*e27+e17*e03*e26+e17*e23*e06+e07*e14*e27+e07*e24*e17+e07*e15*e28+e07*e25*e18+e07*e13*e26+e07*e23*e16+e24*e15*e05+e24*e13*e03+e14*e25*e05+e14*e23*e03+3*e04*e24*e14+e04*e25*e15+e04*e23*e13+e21*e02*e15+e21*e12*e05+e21*e00*e13+e21*e10*e03-e24*e10*e00+e01*e20*e13+e01*e10*e23+e01*e22*e15+e01*e12*e25+e01*e11*e24+e11*e20*e03+e11*e00*e23+e01*e21*e14; +A[4 + 10*6]=e11*e12*e25-0.5*e24*e182-0.5*e24*e102-0.5*e24*e162-0.5*e24*e122+e27*e13*e16+e27*e15*e18-e14*e20*e10-e14*e26*e16-e14*e22*e12-e14*e28*e18+e17*e15*e28+e17*e14*e27+1.5*e24*e142+0.5*e24*e132+0.5*e24*e152+0.5*e112*e24+0.5*e24*e172+e11*e21*e14+e11*e22*e15+e11*e10*e23+e11*e20*e13+e21*e10*e13+e21*e12*e15+e17*e13*e26+e17*e23*e16+e14*e25*e15+e14*e23*e13+e17*e25*e18; +A[4 + 10*7]=e27*e03*e26+e27*e25*e08+e27*e05*e28-e24*e20*e00-e24*e22*e02-e24*e26*e06-e24*e28*e08+0.5*e04*e232+1.5*e04*e242+0.5*e04*e252+0.5*e04*e272-0.5*e04*e202-0.5*e04*e222-0.5*e04*e262-0.5*e04*e282+e24*e23*e03+e24*e25*e05+e07*e23*e26+e07*e24*e27+e07*e25*e28+e27*e23*e06+e21*e20*e03+e21*e00*e23+e21*e22*e05+e21*e02*e25+0.5*e212*e04+e01*e20*e23+e01*e21*e24+e01*e22*e25; +A[4 + 10*8]=-e24*e22*e12-e24*e28*e18+0.5*e14*e272-0.5*e14*e202-0.5*e14*e222-0.5*e14*e262-0.5*e14*e282+e17*e23*e26+e17*e24*e27+e17*e25*e28+e27*e23*e16+e27*e13*e26+e27*e25*e18+e27*e15*e28-e24*e20*e10-e24*e26*e16+0.5*e14*e232+1.5*e14*e242+0.5*e14*e252+e21*e10*e23+e21*e22*e15+e21*e12*e25+e24*e23*e13+e24*e25*e15+e21*e20*e13+0.5*e212*e14+e11*e20*e23+e11*e22*e25+e11*e21*e24; +A[4 + 10*9]=e21*e20*e23+0.5*e212*e24+e21*e22*e25+0.5*e24*e232+0.5*e243+0.5*e24*e252+e27*e23*e26+0.5*e24*e272+e27*e25*e28-0.5*e24*e202-0.5*e24*e222-0.5*e24*e262-0.5*e24*e282; +A[4 + 10*10]=-e04*e38*e08-e04*e32*e02-e04*e36*e06-0.5*e34*e002-0.5*e34*e022-0.5*e34*e062-0.5*e34*e082+e37*e03*e06+e37*e05*e08-e04*e30*e00+0.5*e34*e032+0.5*e34*e052+0.5*e34*e072+1.5*e34*e042+e01*e30*e03+e01*e00*e33+e01*e31*e04+e01*e32*e05+e01*e02*e35+e31*e00*e03+e31*e02*e05+e04*e33*e03+e04*e35*e05+e07*e03*e36+e07*e04*e37+e07*e35*e08+e07*e05*e38+0.5*e012*e34+e07*e33*e06; +A[4 + 10*11]=e07*e13*e36+e01*e12*e35-e04*e30*e10+e17*e04*e37+e17*e35*e08+e17*e05*e38+e37*e13*e06+e37*e03*e16+e37*e15*e08+e37*e05*e18-e04*e36*e16+e17*e33*e06+e04*e33*e13+e04*e35*e15+3*e04*e34*e14+e14*e33*e03+e14*e35*e05+e34*e13*e03+e34*e15*e05+e07*e33*e16+e07*e35*e18+e07*e15*e38+e07*e34*e17+e07*e14*e37+e17*e03*e36+e31*e10*e03+e01*e30*e13+e01*e10*e33+e01*e32*e15+e01*e31*e14+e01*e11*e34+e11*e30*e03+e11*e00*e33+e11*e31*e04+e11*e32*e05+e11*e02*e35+e31*e00*e13+e31*e12*e05+e31*e02*e15-e34*e12*e02-e34*e16*e06-e34*e18*e08-e14*e32*e02-e14*e36*e06-e14*e38*e08-e34*e10*e00-e04*e32*e12-e04*e38*e18-e14*e30*e00; +A[4 + 10*12]=e11*e32*e15-0.5*e34*e102-0.5*e34*e162-0.5*e34*e122-0.5*e34*e182+e37*e13*e16+0.5*e112*e34+1.5*e34*e142+0.5*e34*e132+0.5*e34*e152+0.5*e34*e172+e11*e30*e13+e11*e10*e33+e11*e12*e35+e11*e31*e14+e31*e10*e13+e31*e12*e15+e14*e33*e13+e14*e35*e15+e17*e33*e16+e17*e13*e36+e17*e35*e18+e17*e15*e38+e17*e14*e37+e37*e15*e18-e14*e30*e10-e14*e36*e16-e14*e32*e12-e14*e38*e18; +A[4 + 10*13]=e01*e22*e35-e04*e30*e20-e04*e32*e22+e01*e31*e24+e01*e21*e34+e01*e32*e25+e21*e30*e03+e21*e00*e33+e21*e31*e04+e21*e32*e05+e21*e02*e35+e31*e20*e03+e31*e00*e23+e31*e22*e05+e31*e02*e25+e04*e33*e23+3*e04*e34*e24+e04*e35*e25+e24*e33*e03+e37*e05*e28-e04*e36*e26-e04*e38*e28-e24*e30*e00-e24*e32*e02-e24*e36*e06-e24*e38*e08+e24*e35*e05+e34*e23*e03+e34*e25*e05+e07*e33*e26+e07*e23*e36+e07*e34*e27+e07*e24*e37+e07*e35*e28+e07*e25*e38+e27*e33*e06+e27*e03*e36+e27*e04*e37+e27*e35*e08+e27*e05*e38+e37*e23*e06+e37*e03*e26+e37*e25*e08-e34*e20*e00-e34*e22*e02-e34*e26*e06-e34*e28*e08+e01*e30*e23+e01*e20*e33; +A[4 + 10*14]=e21*e10*e33+e11*e30*e23+e11*e20*e33+e11*e31*e24+e11*e21*e34+e11*e32*e25+e11*e22*e35+e21*e30*e13+e21*e32*e15+e21*e12*e35+e21*e31*e14+e31*e20*e13+e31*e10*e23+e31*e22*e15+e31*e12*e25+e14*e33*e23+3*e14*e34*e24+e14*e35*e25+e24*e33*e13+e24*e35*e15+e34*e23*e13+e34*e25*e15+e17*e33*e26+e17*e23*e36+e17*e34*e27+e17*e24*e37+e17*e35*e28+e17*e25*e38+e27*e33*e16+e27*e13*e36+e27*e35*e18+e27*e15*e38+e27*e14*e37+e37*e23*e16+e37*e13*e26+e37*e25*e18+e37*e15*e28-e34*e28*e18-e34*e22*e12-e14*e32*e22-e14*e36*e26-e14*e38*e28-e24*e30*e10-e24*e36*e16-e24*e32*e12-e24*e38*e18-e34*e20*e10-e34*e26*e16-e14*e30*e20; +A[4 + 10*15]=-0.5*e34*e202-0.5*e34*e222-0.5*e34*e262-0.5*e34*e282+e37*e25*e28-e24*e32*e22-e24*e36*e26-e24*e38*e28-e24*e30*e20+0.5*e212*e34+1.5*e34*e242+0.5*e34*e232+0.5*e34*e252+0.5*e34*e272+e21*e30*e23+e21*e20*e33+e21*e31*e24+e21*e32*e25+e21*e22*e35+e31*e20*e23+e31*e22*e25+e24*e33*e23+e24*e35*e25+e27*e33*e26+e27*e23*e36+e27*e24*e37+e27*e35*e28+e27*e25*e38+e37*e23*e26; +A[4 + 10*16]=e37*e33*e06+e01*e30*e33+e01*e31*e34+e31*e30*e03+e31*e02*e35+e34*e33*e03+e34*e35*e05+e07*e33*e36+e07*e35*e38+e07*e34*e37+e37*e03*e36+e37*e35*e08+e37*e05*e38-e34*e32*e02-e34*e36*e06-e34*e38*e08+e31*e32*e05+e31*e00*e33+0.5*e312*e04+0.5*e04*e332+0.5*e04*e352+1.5*e04*e342+0.5*e04*e372+e01*e32*e35-0.5*e04*e302-0.5*e04*e322-0.5*e04*e362-0.5*e04*e382-e34*e30*e00; +A[4 + 10*17]=0.5*e14*e372-0.5*e14*e302-0.5*e14*e322-0.5*e14*e362-0.5*e14*e382+0.5*e312*e14+0.5*e14*e332+0.5*e14*e352+1.5*e14*e342+e11*e30*e33+e11*e32*e35+e11*e31*e34+e31*e30*e13+e31*e10*e33+e31*e32*e15+e31*e12*e35+e34*e33*e13+e34*e35*e15+e17*e33*e36+e17*e35*e38+e17*e34*e37+e37*e33*e16+e37*e13*e36+e37*e35*e18+e37*e15*e38-e34*e30*e10-e34*e36*e16-e34*e32*e12-e34*e38*e18; +A[4 + 10*18]=-e34*e32*e22-e34*e36*e26-e34*e38*e28+0.5*e24*e332+0.5*e24*e352+1.5*e24*e342+0.5*e24*e372-0.5*e24*e302-0.5*e24*e322-0.5*e24*e362-0.5*e24*e382+e21*e30*e33+0.5*e312*e24+e21*e32*e35+e21*e31*e34+e31*e30*e23+e31*e20*e33+e31*e32*e25+e31*e22*e35+e34*e33*e23+e34*e35*e25+e27*e33*e36+e27*e35*e38+e27*e34*e37+e37*e33*e26+e37*e23*e36+e37*e35*e28+e37*e25*e38-e34*e30*e20; +A[4 + 10*19]=e31*e30*e33+e31*e32*e35+0.5*e312*e34+0.5*e34*e332+0.5*e34*e352+0.5*e343+e37*e33*e36+e37*e35*e38+0.5*e34*e372-0.5*e34*e302-0.5*e34*e322-0.5*e34*e362-0.5*e34*e382; +A[5 + 10*0]=e01*e00*e06+0.5*e012*e07+e01*e02*e08+e04*e03*e06+0.5*e042*e07+e04*e05*e08+0.5*e07*e062+0.5*e073+0.5*e07*e082-0.5*e07*e002-0.5*e07*e022-0.5*e07*e032-0.5*e07*e052; +A[5 + 10*1]=e04*e13*e06+0.5*e042*e17+1.5*e17*e072+0.5*e17*e062+0.5*e17*e082-0.5*e17*e002-0.5*e17*e022-0.5*e17*e032-0.5*e17*e052+e01*e10*e06+e07*e16*e06+e07*e18*e08-e07*e10*e00-e07*e12*e02-e07*e13*e03-e07*e15*e05+e01*e00*e16+e01*e11*e07+e01*e12*e08+e01*e02*e18+e11*e00*e06+e11*e02*e08+e04*e03*e16+e04*e14*e07+e04*e15*e08+e04*e05*e18+e14*e03*e06+e14*e05*e08+0.5*e012*e17; +A[5 + 10*2]=-e17*e10*e00+0.5*e112*e07+0.5*e142*e07+0.5*e07*e162+0.5*e07*e182+1.5*e07*e172-0.5*e07*e102-0.5*e07*e152-0.5*e07*e132-0.5*e07*e122+e01*e10*e16+e01*e12*e18+e01*e11*e17+e11*e10*e06+e11*e00*e16+e11*e12*e08+e11*e02*e18+e04*e13*e16+e04*e15*e18+e04*e14*e17+e14*e13*e06+e14*e03*e16+e14*e15*e08+e14*e05*e18+e17*e16*e06+e17*e18*e08-e17*e12*e02-e17*e13*e03-e17*e15*e05; +A[5 + 10*3]=e11*e10*e16+e11*e12*e18+0.5*e112*e17+e14*e13*e16+e14*e15*e18+0.5*e142*e17+0.5*e17*e162+0.5*e17*e182+0.5*e173-0.5*e17*e102-0.5*e17*e152-0.5*e17*e132-0.5*e17*e122; +A[5 + 10*4]=e01*e22*e08+e07*e28*e08-e07*e20*e00-e07*e23*e03-e07*e22*e02-e07*e25*e05+0.5*e012*e27+0.5*e042*e27+1.5*e27*e072+0.5*e27*e062+0.5*e27*e082-0.5*e27*e002-0.5*e27*e022-0.5*e27*e032-0.5*e27*e052+e07*e26*e06+e01*e20*e06+e01*e00*e26+e01*e21*e07+e01*e02*e28+e21*e00*e06+e21*e02*e08+e04*e23*e06+e04*e03*e26+e04*e24*e07+e04*e25*e08+e04*e05*e28+e24*e03*e06+e24*e05*e08; +A[5 + 10*5]=e14*e24*e07+e14*e03*e26+e14*e23*e06+e04*e14*e27+e04*e24*e17+e04*e15*e28+e04*e25*e18+e04*e13*e26+e04*e23*e16+e21*e02*e18+e21*e12*e08-e27*e15*e05-e27*e13*e03-e27*e12*e02-e27*e10*e00-e17*e25*e05-e17*e23*e03-e17*e22*e02-e17*e20*e00-e07*e22*e12-e07*e23*e13-e07*e25*e15-e07*e20*e10+e27*e18*e08+e27*e16*e06+e17*e28*e08+e17*e26*e06+3*e07*e27*e17+e07*e28*e18+e07*e26*e16+e24*e05*e18+e24*e15*e08+e24*e03*e16+e24*e13*e06+e14*e05*e28+e14*e25*e08+e01*e12*e28+e01*e20*e16+e01*e10*e26+e01*e22*e18+e01*e21*e17+e11*e20*e06+e01*e11*e27+e21*e00*e16+e21*e10*e06+e11*e21*e07+e11*e22*e08+e11*e02*e28+e11*e00*e26; +A[5 + 10*6]=-0.5*e27*e102-0.5*e27*e152-0.5*e27*e132-0.5*e27*e122+0.5*e142*e27+1.5*e27*e172+0.5*e27*e162+0.5*e27*e182+0.5*e112*e27+e11*e22*e18+e11*e10*e26+e11*e20*e16-e17*e22*e12-e17*e23*e13-e17*e25*e15-e17*e20*e10+e17*e28*e18+e17*e26*e16+e24*e15*e18+e24*e13*e16+e14*e24*e17+e14*e15*e28+e14*e25*e18+e14*e13*e26+e14*e23*e16+e21*e12*e18+e21*e10*e16+e11*e21*e17+e11*e12*e28; +A[5 + 10*7]=-0.5*e07*e252+e27*e26*e06+e27*e28*e08-e27*e20*e00-e27*e22*e02-e27*e23*e03-e27*e25*e05+1.5*e07*e272+0.5*e07*e282+e01*e22*e28+e21*e20*e06+e21*e00*e26+e21*e22*e08+e21*e02*e28+e04*e23*e26+e04*e24*e27+e04*e25*e28+e24*e23*e06+e24*e03*e26+e24*e25*e08+e24*e05*e28+0.5*e212*e07+0.5*e242*e07+0.5*e07*e262+e01*e20*e26+e01*e21*e27-0.5*e07*e202-0.5*e07*e232-0.5*e07*e222; +A[5 + 10*8]=-e27*e25*e15-e27*e23*e13-e27*e22*e12-0.5*e17*e252-0.5*e17*e202-0.5*e17*e222-0.5*e17*e232+0.5*e17*e262+1.5*e17*e272+0.5*e17*e282+e24*e23*e16+e24*e13*e26+e24*e25*e18+e24*e15*e28+e27*e26*e16+e27*e28*e18-e27*e20*e10+e14*e24*e27+e14*e25*e28+0.5*e212*e17+0.5*e242*e17+e11*e20*e26+e11*e21*e27+e11*e22*e28+e21*e20*e16+e21*e10*e26+e21*e22*e18+e21*e12*e28+e14*e23*e26; +A[5 + 10*9]=e21*e20*e26+0.5*e212*e27+e21*e22*e28+e24*e23*e26+0.5*e242*e27+e24*e25*e28+0.5*e27*e262+0.5*e273+0.5*e27*e282-0.5*e27*e202-0.5*e27*e222-0.5*e27*e232-0.5*e27*e252; +A[5 + 10*10]=e04*e05*e38+e01*e30*e06-0.5*e37*e002-0.5*e37*e022-0.5*e37*e032-0.5*e37*e052-e07*e32*e02-e07*e35*e05-e07*e33*e03+e07*e36*e06+e07*e38*e08-e07*e30*e00+1.5*e37*e072+0.5*e37*e062+0.5*e37*e082+e01*e02*e38+e31*e00*e06+e31*e02*e08+e04*e33*e06+e04*e03*e36+e04*e34*e07+e04*e35*e08+e34*e03*e06+e34*e05*e08+0.5*e012*e37+0.5*e042*e37+e01*e00*e36+e01*e31*e07+e01*e32*e08; +A[5 + 10*11]=e14*e33*e06+e11*e30*e06+e11*e00*e36+e11*e31*e07+e31*e10*e06+e11*e32*e08+e11*e02*e38+e31*e00*e16+e31*e12*e08+e31*e02*e18+e04*e33*e16+e04*e13*e36+e04*e35*e18+e04*e15*e38+e01*e10*e36+e01*e32*e18+e01*e12*e38+e01*e31*e17+e01*e11*e37+e01*e30*e16-e17*e35*e05-e37*e10*e00-e37*e12*e02-e37*e13*e03-e37*e15*e05+e37*e18*e08-e07*e30*e10-e07*e35*e15-e07*e33*e13-e07*e32*e12-e17*e30*e00-e17*e32*e02-e17*e33*e03+e07*e38*e18+3*e07*e37*e17+e17*e36*e06+e17*e38*e08+e37*e16*e06+e04*e34*e17+e04*e14*e37+e14*e03*e36+e14*e34*e07+e14*e35*e08+e14*e05*e38+e34*e13*e06+e34*e03*e16+e34*e15*e08+e34*e05*e18+e07*e36*e16; +A[5 + 10*12]=e11*e32*e18-0.5*e37*e102-0.5*e37*e152-0.5*e37*e132-0.5*e37*e122+0.5*e112*e37+0.5*e142*e37+1.5*e37*e172+0.5*e37*e162+0.5*e37*e182+e11*e10*e36+e11*e12*e38+e11*e31*e17+e31*e10*e16+e31*e12*e18+e14*e33*e16+e14*e13*e36+e14*e35*e18+e14*e15*e38+e14*e34*e17+e34*e13*e16+e34*e15*e18+e17*e36*e16+e17*e38*e18-e17*e30*e10-e17*e35*e15-e17*e33*e13-e17*e32*e12+e11*e30*e16; +A[5 + 10*13]=e01*e20*e36+e01*e31*e27+e01*e21*e37+e01*e32*e28+e01*e22*e38+e21*e30*e06+e21*e00*e36+e21*e31*e07+e21*e32*e08+e21*e02*e38+e01*e30*e26+e31*e20*e06+e31*e00*e26+e31*e22*e08+e31*e02*e28+e04*e33*e26+e04*e23*e36+e04*e34*e27+e04*e24*e37+e04*e35*e28+e04*e25*e38+e24*e33*e06+e24*e03*e36+e24*e34*e07+e24*e35*e08+e24*e05*e38+e34*e23*e06+e34*e03*e26+e34*e25*e08+e34*e05*e28+e07*e36*e26+3*e07*e37*e27+e07*e38*e28+e27*e36*e06+e27*e38*e08+e37*e26*e06+e37*e28*e08-e07*e30*e20-e07*e32*e22-e07*e33*e23-e07*e35*e25-e27*e30*e00-e27*e32*e02-e27*e33*e03-e27*e35*e05-e37*e20*e00-e37*e22*e02-e37*e23*e03-e37*e25*e05; +A[5 + 10*14]=e11*e30*e26+e11*e20*e36+e11*e31*e27+e11*e21*e37+e11*e32*e28+e11*e22*e38+e21*e10*e36+e21*e32*e18+e21*e12*e38+e21*e31*e17+e31*e20*e16+e31*e10*e26+e31*e22*e18+e31*e12*e28+e14*e33*e26+e14*e23*e36+e14*e34*e27+e14*e24*e37+e14*e35*e28+e14*e25*e38+e24*e33*e16+e24*e13*e36+e24*e35*e18+e24*e15*e38+e24*e34*e17+e34*e23*e16+e34*e13*e26+e34*e25*e18+e34*e15*e28+e17*e36*e26+3*e17*e37*e27+e17*e38*e28+e27*e36*e16+e27*e38*e18+e37*e26*e16+e37*e28*e18-e17*e30*e20-e17*e32*e22-e17*e33*e23-e17*e35*e25-e27*e30*e10-e27*e35*e15-e27*e33*e13-e27*e32*e12-e37*e20*e10-e37*e25*e15-e37*e23*e13-e37*e22*e12+e21*e30*e16; +A[5 + 10*15]=e21*e20*e36+e21*e31*e27+e21*e32*e28+e21*e22*e38+e31*e22*e28+e24*e33*e26+e24*e23*e36+e24*e34*e27+e24*e35*e28+e24*e25*e38+e34*e23*e26+e34*e25*e28+e27*e36*e26+e27*e38*e28-e27*e30*e20-e27*e32*e22-e27*e33*e23-e27*e35*e25+0.5*e242*e37+1.5*e37*e272+0.5*e37*e262+0.5*e37*e282+e31*e20*e26+e21*e30*e26+0.5*e212*e37-0.5*e37*e202-0.5*e37*e222-0.5*e37*e232-0.5*e37*e252; +A[5 + 10*16]=e01*e30*e36+e01*e32*e38+e01*e31*e37+e31*e30*e06+e31*e00*e36+e31*e32*e08+e31*e02*e38+e04*e33*e36+e04*e35*e38+e04*e34*e37+e34*e33*e06+e34*e03*e36+e34*e35*e08+e34*e05*e38+e37*e36*e06+e37*e38*e08-e37*e30*e00-e37*e32*e02-e37*e33*e03-e37*e35*e05+0.5*e312*e07+0.5*e342*e07+0.5*e07*e362+0.5*e07*e382+1.5*e07*e372-0.5*e07*e302-0.5*e07*e352-0.5*e07*e322-0.5*e07*e332; +A[5 + 10*17]=0.5*e312*e17+0.5*e342*e17+0.5*e17*e362+0.5*e17*e382+1.5*e17*e372-0.5*e17*e302-0.5*e17*e352-0.5*e17*e322-0.5*e17*e332-e37*e32*e12-e37*e33*e13+e11*e30*e36+e11*e32*e38+e11*e31*e37+e31*e30*e16+e31*e10*e36+e31*e32*e18+e31*e12*e38+e14*e33*e36+e14*e35*e38+e14*e34*e37+e34*e33*e16+e34*e13*e36+e34*e35*e18+e34*e15*e38+e37*e36*e16+e37*e38*e18-e37*e30*e10-e37*e35*e15; +A[5 + 10*18]=e21*e31*e37-0.5*e27*e332+e21*e30*e36+e21*e32*e38+e31*e30*e26+e31*e20*e36+e31*e32*e28+e31*e22*e38+e24*e33*e36+e24*e35*e38+e24*e34*e37+e34*e33*e26+e34*e23*e36+e34*e35*e28+e34*e25*e38+e37*e36*e26+e37*e38*e28-e37*e30*e20-e37*e32*e22-e37*e33*e23-e37*e35*e25+0.5*e312*e27+0.5*e342*e27+0.5*e27*e362+0.5*e27*e382+1.5*e27*e372-0.5*e27*e302-0.5*e27*e352-0.5*e27*e322; +A[5 + 10*19]=e31*e30*e36+e31*e32*e38+0.5*e312*e37+e34*e33*e36+e34*e35*e38+0.5*e342*e37+0.5*e37*e362+0.5*e37*e382+0.5*e373-0.5*e37*e302-0.5*e37*e352-0.5*e37*e322-0.5*e37*e332; +A[6 + 10*0]=0.5*e02*e002+0.5*e02*e012+0.5*e023+e05*e00*e03+e05*e01*e04+0.5*e02*e052+e08*e00*e06+e08*e01*e07+0.5*e02*e082-0.5*e02*e032-0.5*e02*e042-0.5*e02*e062-0.5*e02*e072; +A[6 + 10*1]=-0.5*e12*e042-0.5*e12*e062-0.5*e12*e072+0.5*e12*e082-0.5*e12*e032+1.5*e12*e022+0.5*e12*e002+0.5*e12*e012+0.5*e12*e052+e02*e10*e00+e02*e11*e01+e05*e10*e03+e05*e00*e13+e05*e11*e04+e05*e01*e14+e05*e02*e15+e15*e00*e03+e15*e01*e04+e08*e10*e06+e08*e00*e16+e08*e11*e07+e08*e01*e17+e08*e02*e18+e18*e00*e06+e18*e01*e07-e02*e13*e03-e02*e14*e04-e02*e16*e06-e02*e17*e07; +A[6 + 10*2]=0.5*e02*e102+1.5*e02*e122+0.5*e02*e112+0.5*e02*e152+0.5*e02*e182-0.5*e02*e162-0.5*e02*e172-0.5*e02*e132-0.5*e02*e142+e12*e10*e00+e12*e11*e01+e05*e10*e13+e05*e12*e15+e05*e11*e14+e15*e10*e03+e15*e00*e13+e15*e11*e04+e15*e01*e14+e08*e10*e16+e08*e12*e18+e08*e11*e17+e18*e10*e06+e18*e00*e16+e18*e11*e07+e18*e01*e17-e12*e13*e03-e12*e14*e04-e12*e16*e06-e12*e17*e07; +A[6 + 10*3]=0.5*e12*e102+0.5*e123+0.5*e12*e112+e15*e10*e13+0.5*e12*e152+e15*e11*e14+e18*e10*e16+0.5*e12*e182+e18*e11*e17-0.5*e12*e162-0.5*e12*e172-0.5*e12*e132-0.5*e12*e142; +A[6 + 10*4]=-0.5*e22*e032-0.5*e22*e042-0.5*e22*e062-0.5*e22*e072+0.5*e22*e082+1.5*e22*e022+0.5*e22*e002+0.5*e22*e012+0.5*e22*e052+e02*e20*e00+e02*e21*e01+e05*e20*e03+e05*e00*e23+e05*e21*e04+e05*e01*e24+e05*e02*e25+e25*e00*e03+e25*e01*e04+e08*e20*e06+e08*e00*e26+e08*e21*e07+e08*e01*e27+e08*e02*e28+e28*e00*e06+e28*e01*e07-e02*e27*e07-e02*e23*e03-e02*e24*e04-e02*e26*e06; +A[6 + 10*5]=-e22*e17*e07-e22*e16*e06-e22*e14*e04-e22*e13*e03-e12*e26*e06-e12*e24*e04-e12*e23*e03-e12*e27*e07-e02*e24*e14-e02*e23*e13-e02*e27*e17-e02*e26*e16+e28*e01*e17+e28*e11*e07+e28*e00*e16+e28*e10*e06+e18*e02*e28+e18*e01*e27+e18*e21*e07+e18*e00*e26+e18*e20*e06+e08*e11*e27+e08*e21*e17+e08*e12*e28+e08*e22*e18+e08*e10*e26+e25*e01*e14+e25*e11*e04+e25*e00*e13+e25*e10*e03+e15*e01*e24+e02*e21*e11+e12*e21*e01+e15*e02*e25+e15*e21*e04+e05*e22*e15+e05*e11*e24+e15*e20*e03+e15*e00*e23+e05*e10*e23+e05*e12*e25+e05*e21*e14+e22*e10*e00+e22*e11*e01+e02*e20*e10+3*e02*e22*e12+e12*e20*e00+e08*e20*e16+e05*e20*e13; +A[6 + 10*6]=-e12*e24*e14-e12*e23*e13-e12*e27*e17-e12*e26*e16+e28*e11*e17+e28*e10*e16+e18*e11*e27+e18*e21*e17+e18*e12*e28+e18*e10*e26+e18*e20*e16+e25*e11*e14+e25*e10*e13+e15*e11*e24+e15*e21*e14+e15*e12*e25+e15*e10*e23+e15*e20*e13+e12*e21*e11+0.5*e22*e182+0.5*e22*e152+1.5*e22*e122+0.5*e22*e102+e12*e20*e10+0.5*e22*e112-0.5*e22*e172-0.5*e22*e132-0.5*e22*e142-0.5*e22*e162; +A[6 + 10*7]=0.5*e02*e282+e28*e01*e27-e22*e27*e07-e22*e23*e03-e22*e24*e04-e22*e26*e06+0.5*e02*e252+e05*e20*e23+e05*e22*e25+e25*e20*e03+e25*e00*e23+e25*e21*e04+e25*e01*e24+e08*e20*e26+e08*e21*e27+e08*e22*e28+e28*e20*e06+e28*e00*e26+e28*e21*e07+e05*e21*e24+0.5*e02*e202+0.5*e02*e212+1.5*e02*e222+e22*e20*e00+e22*e21*e01-0.5*e02*e272-0.5*e02*e242-0.5*e02*e232-0.5*e02*e262; +A[6 + 10*8]=-e22*e27*e17-e22*e23*e13-e22*e24*e14-0.5*e12*e232-0.5*e12*e262-0.5*e12*e242-0.5*e12*e272+0.5*e12*e282+e18*e21*e27+e28*e20*e16+e28*e10*e26+e28*e21*e17+e28*e11*e27-e22*e26*e16+e18*e22*e28+0.5*e12*e252+0.5*e12*e202+0.5*e12*e212+1.5*e12*e222+e22*e20*e10+e15*e20*e23+e15*e21*e24+e15*e22*e25+e25*e20*e13+e25*e10*e23+e25*e21*e14+e25*e11*e24+e18*e20*e26+e22*e21*e11; +A[6 + 10*9]=0.5*e22*e202+0.5*e22*e212+0.5*e223+e25*e20*e23+e25*e21*e24+0.5*e22*e252+e28*e20*e26+e28*e21*e27+0.5*e22*e282-0.5*e22*e232-0.5*e22*e262-0.5*e22*e242-0.5*e22*e272; +A[6 + 10*10]=e08*e31*e07-0.5*e32*e032-e02*e33*e03-e02*e34*e04-e02*e36*e06-0.5*e32*e042-0.5*e32*e062-0.5*e32*e072+e38*e01*e07+e38*e00*e06-e02*e37*e07+e05*e31*e04+e05*e01*e34+e05*e02*e35+e35*e01*e04+e35*e00*e03+e08*e30*e06+e08*e00*e36+e08*e01*e37+e08*e02*e38+0.5*e32*e052+e02*e30*e00+e02*e31*e01+e05*e30*e03+e05*e00*e33+1.5*e32*e022+0.5*e32*e012+0.5*e32*e002+0.5*e32*e082; +A[6 + 10*11]=e05*e32*e15+e32*e11*e01+e38*e10*e06+e08*e12*e38-e32*e14*e04-e32*e16*e06-e32*e17*e07-e12*e36*e06-e32*e13*e03-e02*e34*e14-e12*e37*e07-e12*e33*e03-e12*e34*e04-e02*e37*e17-e02*e33*e13+e38*e01*e17-e02*e36*e16+e18*e01*e37+e18*e02*e38+e38*e00*e16+e38*e11*e07+e08*e30*e16+e08*e10*e36+e08*e32*e18+e08*e31*e17+e08*e11*e37+e18*e30*e06+e18*e00*e36+e18*e31*e07+e35*e10*e03+e35*e00*e13+e35*e11*e04+e35*e01*e14+e15*e02*e35+e05*e10*e33+e05*e12*e35+e05*e31*e14+e05*e11*e34+e15*e30*e03+e15*e00*e33+e15*e31*e04+e15*e01*e34+e05*e30*e13+e02*e30*e10+e02*e31*e11+3*e02*e32*e12+e12*e30*e00+e12*e31*e01+e32*e10*e00; +A[6 + 10*12]=0.5*e32*e102+0.5*e32*e112+e12*e30*e10+1.5*e32*e122+e12*e31*e11+e15*e30*e13+e15*e10*e33+e15*e12*e35+e15*e31*e14+e15*e11*e34+e35*e10*e13-0.5*e32*e162-0.5*e32*e172-0.5*e32*e132-0.5*e32*e142-e12*e37*e17-e12*e33*e13-e12*e34*e14+0.5*e32*e182+0.5*e32*e152+e35*e11*e14+e18*e30*e16+e18*e10*e36+e18*e12*e38+e18*e31*e17+e18*e11*e37+e38*e10*e16+e38*e11*e17-e12*e36*e16; +A[6 + 10*13]=3*e02*e32*e22+e05*e31*e24+e08*e22*e38+e02*e31*e21+e22*e30*e00+e22*e31*e01+e32*e20*e00+e32*e21*e01+e05*e30*e23+e05*e20*e33+e05*e21*e34-e22*e37*e07-e22*e33*e03-e22*e34*e04-e22*e36*e06-e32*e27*e07-e32*e23*e03-e32*e24*e04-e32*e26*e06+e05*e32*e25+e25*e30*e03+e25*e00*e33+e25*e31*e04+e25*e01*e34+e25*e02*e35+e35*e20*e03+e35*e00*e23+e35*e21*e04+e35*e01*e24+e08*e30*e26+e08*e20*e36+e08*e31*e27+e08*e21*e37+e08*e32*e28+e28*e30*e06+e28*e00*e36+e28*e31*e07+e28*e01*e37+e28*e02*e38+e38*e20*e06+e38*e00*e26+e38*e21*e07+e38*e01*e27-e02*e33*e23-e02*e36*e26-e02*e34*e24-e02*e37*e27+e05*e22*e35+e02*e30*e20; +A[6 + 10*14]=e18*e22*e38+e12*e31*e21+3*e12*e32*e22+e22*e30*e10+e22*e31*e11+e32*e20*e10+e32*e21*e11+e15*e30*e23+e15*e20*e33+e15*e31*e24+e15*e21*e34+e15*e32*e25+e15*e22*e35+e25*e30*e13+e25*e10*e33+e25*e12*e35+e25*e31*e14+e25*e11*e34+e35*e20*e13+e35*e10*e23+e35*e21*e14+e35*e11*e24+e18*e30*e26+e18*e20*e36+e18*e31*e27+e18*e21*e37+e18*e32*e28+e28*e30*e16+e28*e10*e36+e28*e12*e38+e28*e31*e17+e28*e11*e37+e38*e20*e16+e38*e10*e26+e12*e30*e20-e22*e37*e17-e22*e33*e13-e22*e34*e14-e32*e26*e16-e32*e27*e17-e32*e23*e13-e32*e24*e14-e22*e36*e16+e38*e21*e17+e38*e11*e27-e12*e33*e23-e12*e36*e26-e12*e34*e24-e12*e37*e27; +A[6 + 10*15]=e25*e30*e23+e22*e30*e20+e22*e31*e21+e25*e20*e33+e25*e31*e24+e25*e21*e34+e25*e22*e35+e35*e20*e23+e35*e21*e24+e28*e30*e26+e28*e20*e36+e28*e31*e27+e28*e21*e37+e28*e22*e38+e38*e20*e26+e38*e21*e27-e22*e33*e23-e22*e36*e26-e22*e34*e24-e22*e37*e27+0.5*e32*e212+0.5*e32*e252+1.5*e32*e222+0.5*e32*e202+0.5*e32*e282-0.5*e32*e232-0.5*e32*e262-0.5*e32*e242-0.5*e32*e272; +A[6 + 10*16]=0.5*e02*e302+1.5*e02*e322+0.5*e02*e312+0.5*e02*e352+0.5*e02*e382-0.5*e02*e342-0.5*e02*e362-0.5*e02*e332-0.5*e02*e372+e38*e30*e06+e32*e30*e00+e32*e31*e01+e05*e30*e33+e05*e32*e35+e05*e31*e34+e35*e30*e03+e35*e00*e33+e35*e31*e04+e35*e01*e34+e08*e30*e36+e08*e32*e38+e08*e31*e37+e38*e00*e36+e38*e31*e07+e38*e01*e37-e32*e37*e07-e32*e33*e03-e32*e34*e04-e32*e36*e06; +A[6 + 10*17]=e32*e30*e10+e32*e31*e11+e15*e30*e33+e15*e32*e35+e15*e31*e34+e35*e30*e13+e35*e10*e33+e35*e31*e14+e35*e11*e34+e18*e30*e36+e18*e32*e38+e18*e31*e37+e38*e30*e16+e38*e10*e36+e38*e31*e17+e38*e11*e37-e32*e36*e16-e32*e37*e17-e32*e33*e13-e32*e34*e14+0.5*e12*e382-0.5*e12*e342-0.5*e12*e362-0.5*e12*e332-0.5*e12*e372+0.5*e12*e352+1.5*e12*e322+0.5*e12*e312+0.5*e12*e302; +A[6 + 10*18]=0.5*e22*e302+0.5*e22*e312+0.5*e22*e352+0.5*e22*e382-0.5*e22*e342-0.5*e22*e362-0.5*e22*e332-0.5*e22*e372+1.5*e22*e322+e32*e30*e20+e32*e31*e21+e25*e30*e33+e25*e32*e35+e25*e31*e34+e35*e30*e23+e35*e20*e33+e35*e31*e24+e35*e21*e34+e28*e30*e36+e28*e32*e38+e28*e31*e37+e38*e30*e26+e38*e20*e36+e38*e31*e27+e38*e21*e37-e32*e33*e23-e32*e36*e26-e32*e34*e24-e32*e37*e27; +A[6 + 10*19]=0.5*e32*e302+0.5*e323+0.5*e32*e312+e35*e30*e33+0.5*e32*e352+e35*e31*e34+e38*e30*e36+0.5*e32*e382+e38*e31*e37-0.5*e32*e342-0.5*e32*e362-0.5*e32*e332-0.5*e32*e372; +A[7 + 10*0]=e02*e01*e04+e02*e00*e03+0.5*e022*e05+0.5*e05*e032+0.5*e05*e042+0.5*e053+e08*e03*e06+e08*e04*e07+0.5*e05*e082-0.5*e05*e002-0.5*e05*e062-0.5*e05*e012-0.5*e05*e072; +A[7 + 10*1]=e08*e13*e06+e02*e10*e03+e02*e00*e13+e02*e11*e04+e02*e01*e14+e02*e12*e05+e12*e01*e04+e12*e00*e03+e05*e13*e03+e05*e14*e04+e08*e03*e16+e08*e14*e07+e08*e04*e17+e08*e05*e18+e18*e03*e06+e18*e04*e07-e05*e10*e00-e05*e11*e01-e05*e16*e06-e05*e17*e07+0.5*e022*e15+1.5*e15*e052+0.5*e15*e032+0.5*e15*e042+0.5*e15*e082-0.5*e15*e002-0.5*e15*e062-0.5*e15*e012-0.5*e15*e072; +A[7 + 10*2]=0.5*e122*e05+0.5*e05*e132+1.5*e05*e152+0.5*e05*e142+0.5*e05*e182-0.5*e05*e102-0.5*e05*e162-0.5*e05*e112-0.5*e05*e172+e02*e10*e13+e02*e12*e15+e02*e11*e14+e12*e10*e03+e12*e00*e13+e12*e11*e04+e12*e01*e14+e15*e13*e03+e15*e14*e04+e08*e13*e16+e08*e15*e18+e08*e14*e17+e18*e13*e06+e18*e03*e16+e18*e14*e07+e18*e04*e17-e15*e11*e01-e15*e16*e06-e15*e17*e07-e15*e10*e00; +A[7 + 10*3]=e12*e10*e13+0.5*e122*e15+e12*e11*e14+0.5*e15*e132+0.5*e153+0.5*e15*e142+e18*e13*e16+0.5*e15*e182+e18*e14*e17-0.5*e15*e102-0.5*e15*e162-0.5*e15*e112-0.5*e15*e172; +A[7 + 10*4]=0.5*e25*e082-0.5*e25*e002-0.5*e25*e062-0.5*e25*e012-0.5*e25*e072+e02*e20*e03+e02*e00*e23+e02*e21*e04+e02*e01*e24+e02*e22*e05+e22*e01*e04+e22*e00*e03+e05*e23*e03+e05*e24*e04+e08*e23*e06+e08*e03*e26+e08*e24*e07+e08*e04*e27+e08*e05*e28+e28*e03*e06+e28*e04*e07-e05*e20*e00-e05*e27*e07-e05*e21*e01-e05*e26*e06+0.5*e022*e25+1.5*e25*e052+0.5*e25*e032+0.5*e25*e042; +A[7 + 10*5]=-e25*e17*e07-e25*e16*e06-e25*e11*e01-e25*e10*e00-e15*e26*e06-e15*e21*e01-e15*e27*e07-e15*e20*e00-e05*e27*e17-e05*e21*e11-e05*e26*e16-e05*e20*e10+e28*e04*e17+e28*e14*e07+e28*e03*e16+e28*e13*e06+e18*e05*e28+e18*e04*e27+e18*e24*e07+e18*e03*e26+e18*e23*e06+e08*e14*e27+e08*e24*e17+e08*e15*e28+e08*e25*e18+e08*e13*e26+e08*e23*e16+e25*e14*e04+e25*e13*e03+e15*e24*e04+e15*e23*e03+e05*e24*e14+3*e05*e25*e15+e05*e23*e13+e22*e01*e14+e22*e11*e04+e22*e00*e13+e22*e10*e03+e12*e22*e05+e12*e01*e24+e12*e21*e04+e12*e00*e23+e12*e20*e03+e02*e11*e24+e02*e21*e14+e02*e12*e25+e02*e22*e15+e02*e10*e23+e02*e20*e13; +A[7 + 10*6]=-e15*e27*e17-e15*e21*e11-e15*e26*e16+e28*e14*e17+e28*e13*e16+e18*e14*e27+e18*e24*e17+e18*e15*e28+e18*e13*e26+e15*e24*e14+e15*e23*e13+e22*e11*e14+e22*e10*e13+e12*e11*e24+e12*e21*e14+e12*e22*e15+e12*e10*e23+e18*e23*e16+0.5*e25*e142+0.5*e25*e182+1.5*e25*e152+0.5*e25*e132+0.5*e122*e25+e12*e20*e13-0.5*e25*e172-0.5*e25*e162-0.5*e25*e112-0.5*e25*e102-e15*e20*e10; +A[7 + 10*7]=e28*e24*e07-0.5*e05*e272-0.5*e05*e262-0.5*e05*e212+0.5*e05*e282-0.5*e05*e202+e28*e23*e06+e08*e23*e26+e08*e25*e28+e08*e24*e27+e28*e03*e26+e28*e04*e27-e25*e27*e07-e25*e21*e01-e25*e26*e06+e02*e20*e23+e02*e22*e25+e02*e21*e24+e22*e20*e03+e22*e00*e23+e22*e21*e04+e22*e01*e24+e25*e23*e03+e25*e24*e04+0.5*e222*e05+0.5*e05*e232+1.5*e05*e252+0.5*e05*e242-e25*e20*e00; +A[7 + 10*8]=-0.5*e15*e202-0.5*e15*e262-0.5*e15*e212-0.5*e15*e272+e18*e23*e26+e18*e25*e28+e18*e24*e27+e28*e23*e16+e28*e13*e26+e28*e24*e17+e28*e14*e27-e25*e20*e10-e25*e26*e16-e25*e21*e11-e25*e27*e17+0.5*e15*e282+0.5*e15*e232+1.5*e15*e252+0.5*e15*e242+0.5*e222*e15+e12*e21*e24+e22*e20*e13+e22*e10*e23+e22*e21*e14+e22*e11*e24+e25*e23*e13+e25*e24*e14+e12*e20*e23+e12*e22*e25; +A[7 + 10*9]=e22*e20*e23+0.5*e222*e25+e22*e21*e24+0.5*e25*e232+0.5*e253+0.5*e25*e242+e28*e23*e26+0.5*e25*e282+e28*e24*e27-0.5*e25*e202-0.5*e25*e262-0.5*e25*e212-0.5*e25*e272; +A[7 + 10*10]=-0.5*e35*e062-0.5*e35*e012-0.5*e35*e072-e05*e30*e00-e05*e31*e01-e05*e36*e06-e05*e37*e07-0.5*e35*e002+0.5*e35*e082+e05*e34*e04+e08*e33*e06+e08*e03*e36+e08*e34*e07+e08*e04*e37+e08*e05*e38+e38*e04*e07+e38*e03*e06+0.5*e022*e35+1.5*e35*e052+0.5*e35*e042+0.5*e35*e032+e02*e30*e03+e02*e00*e33+e02*e31*e04+e02*e01*e34+e02*e32*e05+e32*e01*e04+e32*e00*e03+e05*e33*e03; +A[7 + 10*11]=e08*e33*e16-e35*e16*e06-e35*e17*e07-e15*e30*e00-e15*e37*e07-e15*e31*e01-e15*e36*e06-e35*e10*e00-e35*e11*e01-e05*e37*e17-e05*e31*e11+e38*e04*e17-e05*e30*e10-e05*e36*e16+e18*e33*e06+e18*e03*e36+e18*e34*e07+e18*e04*e37+e18*e05*e38+e38*e13*e06+e38*e03*e16+e38*e14*e07+e35*e14*e04+e08*e13*e36+e08*e35*e18+e08*e15*e38+e08*e34*e17+e08*e14*e37+e35*e13*e03+e05*e33*e13+3*e05*e35*e15+e05*e34*e14+e15*e33*e03+e15*e34*e04+e12*e01*e34+e12*e32*e05+e32*e10*e03+e32*e00*e13+e32*e11*e04+e32*e01*e14+e12*e30*e03+e02*e30*e13+e02*e32*e15+e02*e10*e33+e02*e12*e35+e12*e00*e33+e02*e31*e14+e02*e11*e34+e12*e31*e04; +A[7 + 10*12]=-0.5*e35*e162-0.5*e35*e172-e15*e36*e16-e15*e31*e11-e15*e37*e17-0.5*e35*e102-0.5*e35*e112-e15*e30*e10+e18*e13*e36+e18*e15*e38+e18*e34*e17+e18*e14*e37+e38*e13*e16+e38*e14*e17+e18*e33*e16+1.5*e35*e152+0.5*e35*e132+0.5*e35*e142+0.5*e35*e182+0.5*e122*e35+e32*e10*e13+e32*e11*e14+e15*e33*e13+e15*e34*e14+e12*e10*e33+e12*e32*e15+e12*e31*e14+e12*e11*e34+e12*e30*e13; +A[7 + 10*13]=e05*e33*e23+3*e05*e35*e25+e05*e34*e24+e25*e33*e03+e25*e34*e04+e35*e23*e03+e35*e24*e04+e08*e33*e26+e08*e23*e36+e08*e35*e28+e02*e20*e33+e02*e32*e25+e02*e22*e35+e02*e31*e24+e02*e21*e34+e22*e30*e03+e22*e00*e33+e22*e31*e04+e22*e01*e34+e22*e32*e05+e32*e20*e03+e32*e00*e23+e32*e21*e04+e32*e01*e24+e02*e30*e23-e35*e27*e07-e35*e21*e01-e35*e26*e06+e08*e25*e38+e08*e34*e27+e08*e24*e37+e28*e33*e06+e28*e03*e36+e28*e34*e07+e28*e04*e37+e28*e05*e38+e38*e23*e06+e38*e03*e26+e38*e24*e07+e38*e04*e27-e05*e30*e20-e05*e36*e26-e05*e31*e21-e05*e37*e27-e25*e30*e00-e25*e37*e07-e25*e31*e01-e25*e36*e06-e35*e20*e00; +A[7 + 10*14]=e12*e21*e34+e18*e25*e38+e12*e30*e23+e12*e20*e33+e12*e32*e25+e12*e22*e35+e12*e31*e24+e22*e30*e13+e22*e10*e33+e22*e32*e15+e22*e31*e14+e22*e11*e34+e32*e20*e13+e32*e10*e23+e32*e21*e14-e25*e30*e10-e25*e36*e16-e25*e31*e11-e25*e37*e17-e35*e20*e10-e35*e26*e16-e35*e21*e11-e35*e27*e17+e15*e33*e23+3*e15*e35*e25+e15*e34*e24+e25*e33*e13+e25*e34*e14+e35*e23*e13+e35*e24*e14+e18*e33*e26+e18*e23*e36+e18*e35*e28+e18*e34*e27+e18*e24*e37+e28*e33*e16+e28*e13*e36+e28*e15*e38+e28*e34*e17+e28*e14*e37+e38*e23*e16+e38*e13*e26+e38*e24*e17+e38*e14*e27-e15*e30*e20-e15*e36*e26-e15*e31*e21-e15*e37*e27+e32*e11*e24; +A[7 + 10*15]=-0.5*e35*e202-0.5*e35*e262-0.5*e35*e212-0.5*e35*e272+e25*e34*e24+e28*e23*e36+e28*e25*e38+e28*e34*e27+e28*e24*e37+e38*e23*e26+e38*e24*e27-e25*e30*e20-e25*e36*e26-e25*e31*e21-e25*e37*e27+e25*e33*e23+0.5*e222*e35+1.5*e35*e252+0.5*e35*e232+0.5*e35*e242+0.5*e35*e282+e22*e30*e23+e22*e20*e33+e22*e32*e25+e22*e31*e24+e22*e21*e34+e32*e20*e23+e32*e21*e24+e28*e33*e26; +A[7 + 10*16]=-e35*e30*e00-e35*e31*e01-e35*e36*e06-e35*e37*e07+0.5*e322*e05+0.5*e05*e332+0.5*e05*e342+1.5*e05*e352+0.5*e05*e382-0.5*e05*e302-0.5*e05*e362-0.5*e05*e312-0.5*e05*e372+e02*e30*e33+e02*e31*e34+e02*e32*e35+e32*e30*e03+e32*e00*e33+e32*e31*e04+e32*e01*e34+e35*e33*e03+e35*e34*e04+e08*e33*e36+e08*e34*e37+e08*e35*e38+e38*e33*e06+e38*e03*e36+e38*e34*e07+e38*e04*e37; +A[7 + 10*17]=-e35*e30*e10+e12*e32*e35-0.5*e15*e362-0.5*e15*e312-0.5*e15*e372-e35*e36*e16+0.5*e322*e15+0.5*e15*e332+0.5*e15*e342+1.5*e15*e352+0.5*e15*e382-0.5*e15*e302+e12*e30*e33+e12*e31*e34+e32*e30*e13+e32*e10*e33+e32*e31*e14+e32*e11*e34+e35*e33*e13+e35*e34*e14+e18*e33*e36+e18*e34*e37+e18*e35*e38+e38*e33*e16+e38*e13*e36+e38*e34*e17+e38*e14*e37-e35*e31*e11-e35*e37*e17; +A[7 + 10*18]=-0.5*e25*e302-0.5*e25*e362-0.5*e25*e312-0.5*e25*e372+0.5*e322*e25+0.5*e25*e332+0.5*e25*e342+1.5*e25*e352+0.5*e25*e382+e22*e30*e33+e22*e31*e34+e22*e32*e35+e32*e30*e23+e32*e20*e33+e32*e31*e24+e32*e21*e34+e35*e33*e23+e35*e34*e24+e28*e33*e36+e28*e34*e37+e28*e35*e38+e38*e33*e26+e38*e23*e36+e38*e34*e27+e38*e24*e37-e35*e30*e20-e35*e36*e26-e35*e31*e21-e35*e37*e27; +A[7 + 10*19]=e32*e30*e33+e32*e31*e34+0.5*e322*e35+0.5*e35*e332+0.5*e35*e342+0.5*e353+e38*e33*e36+e38*e34*e37+0.5*e35*e382-0.5*e35*e302-0.5*e35*e362-0.5*e35*e312-0.5*e35*e372; +A[8 + 10*0]=e02*e00*e06+e02*e01*e07+0.5*e022*e08+e05*e04*e07+e05*e03*e06+0.5*e052*e08+0.5*e08*e062+0.5*e08*e072+0.5*e083-0.5*e08*e042-0.5*e08*e002-0.5*e08*e012-0.5*e08*e032; +A[8 + 10*1]=e02*e10*e06+e02*e00*e16+e02*e11*e07+e02*e01*e17+e02*e12*e08+e12*e00*e06+e12*e01*e07+e05*e13*e06+e05*e03*e16+e05*e14*e07+e05*e04*e17+e05*e15*e08+e15*e04*e07+e15*e03*e06+e08*e16*e06+e08*e17*e07-e08*e10*e00-e08*e11*e01-e08*e13*e03-e08*e14*e04+0.5*e022*e18+0.5*e052*e18+1.5*e18*e082+0.5*e18*e062+0.5*e18*e072-0.5*e18*e042-0.5*e18*e002-0.5*e18*e012-0.5*e18*e032; +A[8 + 10*2]=e12*e01*e17+0.5*e152*e08+0.5*e08*e162+1.5*e08*e182+0.5*e08*e172-0.5*e08*e102-0.5*e08*e112-0.5*e08*e132-0.5*e08*e142+e05*e13*e16+e05*e14*e17+e05*e15*e18+e15*e13*e06+e15*e03*e16+e15*e14*e07+e15*e04*e17+e18*e16*e06+e18*e17*e07-e18*e10*e00-e18*e11*e01-e18*e13*e03-e18*e14*e04+0.5*e122*e08+e02*e10*e16+e02*e12*e18+e02*e11*e17+e12*e10*e06+e12*e00*e16+e12*e11*e07; +A[8 + 10*3]=e12*e10*e16+0.5*e122*e18+e12*e11*e17+e15*e13*e16+e15*e14*e17+0.5*e152*e18+0.5*e18*e162+0.5*e183+0.5*e18*e172-0.5*e18*e102-0.5*e18*e112-0.5*e18*e132-0.5*e18*e142; +A[8 + 10*4]=-e08*e20*e00+e08*e27*e07-e08*e21*e01-e08*e23*e03-e08*e24*e04+e02*e20*e06+e02*e00*e26+e02*e21*e07+e02*e01*e27+e02*e22*e08+e22*e00*e06+e22*e01*e07+e05*e23*e06+e05*e03*e26+e05*e24*e07+e05*e04*e27+e05*e25*e08+e25*e04*e07+e25*e03*e06+e08*e26*e06+0.5*e022*e28+0.5*e052*e28+1.5*e28*e082+0.5*e28*e062+0.5*e28*e072-0.5*e28*e042-0.5*e28*e002-0.5*e28*e012-0.5*e28*e032; +A[8 + 10*5]=e22*e10*e06+e22*e11*e07+e22*e01*e17+e05*e23*e16+e05*e13*e26+e05*e25*e18+e05*e15*e28+e05*e24*e17+e05*e14*e27+e15*e23*e06+e15*e03*e26+e15*e24*e07+e15*e04*e27+e15*e25*e08+e25*e13*e06+e25*e03*e16+e25*e14*e07+e25*e04*e17+e08*e26*e16+3*e08*e28*e18+e08*e27*e17+e18*e26*e06+e18*e27*e07+e22*e00*e16+e28*e16*e06+e28*e17*e07-e08*e20*e10-e08*e21*e11-e08*e23*e13-e08*e24*e14-e18*e20*e00-e18*e21*e01-e18*e23*e03-e18*e24*e04-e28*e10*e00-e28*e11*e01-e28*e13*e03-e28*e14*e04+e02*e20*e16+e02*e10*e26+e02*e22*e18+e02*e12*e28+e02*e21*e17+e02*e11*e27+e12*e20*e06+e12*e00*e26+e12*e21*e07+e12*e01*e27+e12*e22*e08; +A[8 + 10*6]=-e18*e24*e14-e18*e21*e11-e18*e23*e13-e18*e20*e10+e18*e27*e17+e18*e26*e16+e25*e14*e17+e25*e13*e16+e15*e25*e18+e15*e14*e27+e15*e24*e17+e15*e13*e26+e15*e23*e16+e22*e11*e17+e22*e10*e16+e12*e11*e27+e12*e21*e17+e12*e22*e18+e12*e10*e26+e12*e20*e16+0.5*e28*e162+0.5*e28*e172+1.5*e28*e182+0.5*e152*e28-0.5*e28*e142-0.5*e28*e112-0.5*e28*e132-0.5*e28*e102+0.5*e122*e28; +A[8 + 10*7]=-e28*e24*e04-e28*e21*e01-e28*e23*e03-e28*e20*e00+e28*e27*e07+e28*e26*e06+e25*e04*e27+e25*e24*e07+e25*e03*e26+e05*e24*e27+e05*e25*e28+e05*e23*e26+e22*e01*e27+e22*e21*e07+e22*e00*e26+e22*e20*e06+e02*e22*e28+e02*e20*e26+e02*e21*e27+0.5*e222*e08-0.5*e08*e242-0.5*e08*e212-0.5*e08*e232-0.5*e08*e202+0.5*e08*e262+0.5*e08*e272+1.5*e08*e282+0.5*e252*e08+e25*e23*e06; +A[8 + 10*8]=e25*e24*e17+e25*e14*e27+e28*e26*e16+e28*e27*e17-e28*e21*e11-e28*e24*e14+e12*e22*e28+e22*e10*e26+e22*e21*e17+e22*e11*e27+e15*e23*e26+e15*e25*e28+e15*e24*e27+e25*e23*e16+e25*e13*e26+e22*e20*e16+0.5*e222*e18+0.5*e252*e18+0.5*e18*e262+0.5*e18*e272+e12*e20*e26+e12*e21*e27-e28*e20*e10-0.5*e18*e232-0.5*e18*e242-e28*e23*e13-0.5*e18*e212+1.5*e18*e282-0.5*e18*e202; +A[8 + 10*9]=e22*e20*e26+e22*e21*e27+0.5*e222*e28+e25*e23*e26+0.5*e252*e28+e25*e24*e27+0.5*e28*e262+0.5*e28*e272+0.5*e283-0.5*e28*e202-0.5*e28*e212-0.5*e28*e232-0.5*e28*e242; +A[8 + 10*10]=-e08*e30*e00-0.5*e38*e042-0.5*e38*e002-0.5*e38*e012-0.5*e38*e032+1.5*e38*e082+0.5*e38*e062+0.5*e38*e072+e32*e01*e07+e05*e33*e06+e05*e03*e36+e05*e34*e07+e05*e04*e37+e05*e35*e08+e35*e04*e07+e35*e03*e06+e08*e36*e06+e08*e37*e07+0.5*e052*e38+e32*e00*e06+e02*e30*e06+e02*e00*e36+e02*e31*e07+e02*e01*e37+e02*e32*e08+0.5*e022*e38-e08*e33*e03-e08*e31*e01-e08*e34*e04; +A[8 + 10*11]=-e38*e11*e01-e38*e14*e04-e38*e10*e00-e38*e13*e03-e18*e30*e00-e18*e33*e03-e18*e31*e01-e18*e34*e04-e08*e30*e10-e08*e33*e13-e08*e31*e11-e08*e34*e14+3*e08*e38*e18+e08*e37*e17+e18*e36*e06+e18*e37*e07+e38*e16*e06+e38*e17*e07+e15*e35*e08+e35*e13*e06+e35*e03*e16+e35*e14*e07+e35*e04*e17+e08*e36*e16+e05*e35*e18+e05*e15*e38+e15*e33*e06+e15*e03*e36+e15*e34*e07+e15*e04*e37+e05*e14*e37+e12*e30*e06+e12*e31*e07+e12*e01*e37+e12*e00*e36+e12*e32*e08+e32*e10*e06+e32*e00*e16+e32*e11*e07+e32*e01*e17+e05*e33*e16+e05*e13*e36+e05*e34*e17+e02*e30*e16+e02*e10*e36+e02*e32*e18+e02*e12*e38+e02*e31*e17+e02*e11*e37; +A[8 + 10*12]=e12*e30*e16+e12*e10*e36+e12*e32*e18+e12*e31*e17+e12*e11*e37+e32*e10*e16+e32*e11*e17+e15*e33*e16+e15*e13*e36-0.5*e38*e102-0.5*e38*e112-0.5*e38*e132-0.5*e38*e142+0.5*e38*e162+0.5*e38*e172+e15*e34*e17+e15*e14*e37+e15*e35*e18+e35*e13*e16+e35*e14*e17+e18*e36*e16+e18*e37*e17-e18*e30*e10-e18*e33*e13-e18*e31*e11-e18*e34*e14+0.5*e122*e38+0.5*e152*e38+1.5*e38*e182; +A[8 + 10*13]=e22*e30*e06-e28*e34*e04+e05*e35*e28+e02*e22*e38+e22*e00*e36+e22*e31*e07+e22*e01*e37+e02*e32*e28+e02*e21*e37-e38*e20*e00-e28*e31*e01-e38*e23*e03-e38*e21*e01-e38*e24*e04-e28*e30*e00-e08*e30*e20-e08*e31*e21-e08*e33*e23-e08*e34*e24-e28*e33*e03+e35*e24*e07+e35*e04*e27+e08*e36*e26+e08*e37*e27+3*e08*e38*e28+e28*e36*e06+e28*e37*e07+e38*e26*e06+e38*e27*e07+e25*e04*e37+e25*e35*e08+e35*e23*e06+e35*e03*e26+e05*e23*e36+e05*e25*e38+e05*e34*e27+e05*e24*e37+e25*e33*e06+e25*e03*e36+e25*e34*e07+e05*e33*e26+e32*e21*e07+e32*e01*e27+e22*e32*e08+e32*e20*e06+e32*e00*e26+e02*e30*e26+e02*e20*e36+e02*e31*e27; +A[8 + 10*14]=e35*e13*e26-e38*e21*e11-e38*e24*e14+e35*e24*e17+e35*e14*e27+e18*e36*e26+e18*e37*e27+3*e18*e38*e28+e28*e36*e16+e28*e37*e17+e38*e26*e16+e38*e27*e17-e18*e30*e20-e18*e31*e21-e18*e33*e23-e18*e34*e24-e28*e30*e10-e28*e33*e13-e28*e31*e11-e28*e34*e14-e38*e20*e10-e38*e23*e13+e35*e23*e16+e12*e20*e36+e12*e30*e26+e12*e31*e27+e12*e21*e37+e12*e32*e28+e12*e22*e38+e22*e30*e16+e22*e10*e36+e22*e32*e18+e22*e31*e17+e22*e11*e37+e32*e20*e16+e32*e10*e26+e32*e21*e17+e32*e11*e27+e15*e33*e26+e15*e23*e36+e15*e35*e28+e15*e25*e38+e15*e34*e27+e15*e24*e37+e25*e33*e16+e25*e13*e36+e25*e34*e17+e25*e14*e37+e25*e35*e18; +A[8 + 10*15]=-e28*e30*e20+e22*e30*e26+e22*e20*e36+e22*e31*e27+e22*e21*e37+e22*e32*e28+e32*e20*e26+e32*e21*e27+e25*e33*e26+e25*e23*e36+e25*e35*e28+e25*e34*e27+e25*e24*e37+e35*e23*e26+e35*e24*e27+e28*e36*e26+e28*e37*e27-e28*e31*e21-e28*e33*e23-e28*e34*e24-0.5*e38*e242+0.5*e252*e38+1.5*e38*e282+0.5*e38*e262+0.5*e38*e272-0.5*e38*e202-0.5*e38*e212-0.5*e38*e232+0.5*e222*e38; +A[8 + 10*16]=-0.5*e08*e312-0.5*e08*e342+0.5*e352*e08+0.5*e08*e362+1.5*e08*e382+0.5*e08*e372-0.5*e08*e302-0.5*e08*e332+e02*e30*e36+e02*e32*e38+e02*e31*e37+e32*e30*e06+e32*e00*e36+e32*e31*e07+e32*e01*e37+e05*e33*e36+e05*e34*e37+e05*e35*e38+e35*e33*e06+e35*e03*e36+e35*e34*e07+e35*e04*e37+0.5*e322*e08+e38*e36*e06+e38*e37*e07-e38*e30*e00-e38*e33*e03-e38*e31*e01-e38*e34*e04; +A[8 + 10*17]=-e38*e30*e10+e38*e36*e16+e38*e37*e17-e38*e33*e13-e38*e31*e11-e38*e34*e14+0.5*e18*e362+e12*e30*e36+e12*e32*e38+e12*e31*e37+e32*e30*e16+e32*e10*e36+e32*e31*e17+e32*e11*e37+e15*e33*e36+e15*e34*e37+e15*e35*e38+e35*e33*e16+e35*e13*e36+e35*e34*e17+e35*e14*e37+0.5*e322*e18+0.5*e352*e18+1.5*e18*e382+0.5*e18*e372-0.5*e18*e302-0.5*e18*e332-0.5*e18*e312-0.5*e18*e342; +A[8 + 10*18]=-e38*e30*e20+e25*e35*e38+e22*e30*e36+e22*e32*e38+e22*e31*e37+e32*e30*e26+e32*e20*e36+e32*e31*e27+e32*e21*e37+e25*e33*e36+e25*e34*e37+e35*e33*e26+e35*e23*e36+e35*e34*e27+e35*e24*e37+e38*e36*e26+e38*e37*e27-e38*e31*e21-e38*e33*e23-e38*e34*e24-0.5*e28*e332-0.5*e28*e312-0.5*e28*e342+0.5*e322*e28+0.5*e352*e28+0.5*e28*e362+1.5*e28*e382+0.5*e28*e372-0.5*e28*e302; +A[8 + 10*19]=e32*e30*e36+0.5*e322*e38+e32*e31*e37+e35*e33*e36+e35*e34*e37+0.5*e352*e38+0.5*e38*e362+0.5*e383+0.5*e38*e372-0.5*e38*e302-0.5*e38*e332-0.5*e38*e312-0.5*e38*e342; +A[9 + 10*0]=e00*e04*e08-e00*e05*e07+e03*e02*e07-e03*e01*e08-e06*e02*e04+e06*e01*e05; +A[9 + 10*1]=e06*e01*e15-e16*e02*e04+e16*e01*e05+e03*e02*e17-e13*e01*e08+e06*e11*e05+e13*e02*e07+e00*e04*e18+e00*e14*e08-e00*e05*e17-e10*e05*e07-e00*e15*e07-e06*e12*e04-e06*e02*e14-e03*e01*e18-e03*e11*e08+e10*e04*e08+e03*e12*e07; +A[9 + 10*2]=-e13*e01*e18-e13*e11*e08+e13*e12*e07+e13*e02*e17+e03*e12*e17-e10*e15*e07+e10*e04*e18+e10*e14*e08-e10*e05*e17-e00*e15*e17+e00*e14*e18+e16*e01*e15+e06*e11*e15-e06*e12*e14-e16*e12*e04-e16*e02*e14+e16*e11*e05-e03*e11*e18; +A[9 + 10*3]=e10*e14*e18-e10*e15*e17-e13*e11*e18+e13*e12*e17+e16*e11*e15-e16*e12*e14; +A[9 + 10*4]=-e20*e05*e07+e03*e22*e07+e06*e21*e05+e06*e01*e25-e23*e01*e08+e23*e02*e07+e00*e24*e08-e00*e25*e07-e00*e05*e27+e00*e04*e28-e06*e22*e04-e06*e02*e24-e03*e21*e08-e03*e01*e28-e26*e02*e04+e26*e01*e05+e03*e02*e27+e20*e04*e08; +A[9 + 10*5]=e23*e12*e07-e26*e02*e14+e16*e21*e05-e23*e11*e08+e10*e24*e08-e20*e05*e17+e26*e11*e05+e26*e01*e15+e10*e04*e28+e00*e24*e18-e00*e15*e27+e03*e22*e17-e13*e01*e28+e23*e02*e17+e16*e01*e25+e20*e04*e18+e06*e11*e25+e13*e02*e27-e23*e01*e18-e20*e15*e07-e10*e25*e07+e13*e22*e07-e06*e22*e14-e26*e12*e04-e03*e11*e28-e03*e21*e18-e16*e22*e04-e16*e02*e24-e06*e12*e24+e06*e21*e15+e00*e14*e28-e00*e25*e17+e20*e14*e08-e13*e21*e08-e10*e05*e27+e03*e12*e27; +A[9 + 10*6]=-e13*e11*e28+e13*e12*e27+e13*e22*e17+e16*e11*e25+e10*e14*e28-e13*e21*e18-e23*e11*e18+e23*e12*e17+e20*e14*e18-e20*e15*e17+e26*e11*e15-e10*e15*e27-e10*e25*e17-e16*e22*e14-e16*e12*e24+e16*e21*e15-e26*e12*e14+e10*e24*e18; +A[9 + 10*7]=e26*e21*e05+e26*e01*e25+e20*e04*e28+e20*e24*e08-e20*e25*e07+e23*e22*e07+e03*e22*e27-e03*e21*e28-e26*e22*e04-e20*e05*e27-e00*e25*e27+e06*e21*e25-e06*e22*e24+e00*e24*e28-e26*e02*e24-e23*e21*e08-e23*e01*e28+e23*e02*e27; +A[9 + 10*8]=-e10*e25*e27+e10*e24*e28-e20*e15*e27-e20*e25*e17+e20*e14*e28+e20*e24*e18+e26*e11*e25+e23*e22*e17-e23*e11*e28+e23*e12*e27-e23*e21*e18-e13*e21*e28+e13*e22*e27-e26*e12*e24+e26*e21*e15-e16*e22*e24+e16*e21*e25-e26*e22*e14; +A[9 + 10*9]=-e20*e25*e27+e20*e24*e28-e23*e21*e28+e23*e22*e27-e26*e22*e24+e26*e21*e25; +A[9 + 10*10]=e03*e02*e37-e03*e31*e08-e03*e01*e38+e03*e32*e07-e00*e35*e07+e30*e04*e08+e06*e31*e05-e36*e02*e04+e36*e01*e05-e06*e32*e04-e06*e02*e34+e06*e01*e35+e00*e04*e38-e00*e05*e37+e33*e02*e07-e33*e01*e08-e30*e05*e07+e00*e34*e08; +A[9 + 10*11]=-e36*e12*e04+e30*e04*e18-e30*e15*e07-e36*e02*e14-e30*e05*e17+e30*e14*e08-e00*e35*e17-e00*e15*e37+e33*e02*e17-e06*e32*e14-e06*e12*e34-e16*e32*e04+e06*e31*e15+e06*e11*e35+e00*e34*e18-e10*e35*e07-e33*e11*e08-e33*e01*e18+e16*e01*e35-e16*e02*e34+e16*e31*e05-e03*e31*e18-e03*e11*e38+e03*e32*e17+e13*e02*e37-e13*e31*e08-e13*e01*e38+e10*e34*e08+e00*e14*e38+e36*e11*e05+e36*e01*e15+e03*e12*e37-e10*e05*e37+e10*e04*e38+e33*e12*e07+e13*e32*e07; +A[9 + 10*12]=-e36*e12*e14-e30*e15*e17+e13*e32*e17-e13*e31*e18-e33*e11*e18+e33*e12*e17+e10*e14*e38+e30*e14*e18-e13*e11*e38+e13*e12*e37-e10*e35*e17+e10*e34*e18-e16*e12*e34-e16*e32*e14+e16*e11*e35+e16*e31*e15+e36*e11*e15-e10*e15*e37; +A[9 + 10*13]=-e06*e22*e34-e06*e32*e24-e00*e25*e37-e00*e35*e27+e23*e02*e37+e00*e24*e38-e23*e01*e38-e03*e31*e28-e33*e01*e28+e03*e22*e37+e03*e32*e27+e33*e02*e27-e03*e21*e38-e26*e32*e04-e33*e21*e08+e36*e01*e25+e36*e21*e05-e20*e05*e37+e20*e04*e38+e30*e04*e28-e20*e35*e07+e33*e22*e07+e30*e24*e08-e30*e25*e07-e23*e31*e08+e23*e32*e07+e00*e34*e28+e06*e21*e35+e06*e31*e25-e36*e02*e24+e26*e01*e35-e36*e22*e04+e26*e31*e05-e26*e02*e34+e20*e34*e08-e30*e05*e27; +A[9 + 10*14]=e33*e22*e17+e33*e12*e27+e16*e21*e35-e16*e22*e34-e16*e32*e24+e23*e32*e17-e23*e11*e38-e23*e31*e18+e23*e12*e37-e13*e21*e38-e13*e31*e28+e13*e22*e37+e36*e21*e15-e36*e12*e24+e36*e11*e25-e26*e12*e34-e20*e35*e17+e20*e14*e38+e20*e34*e18+e30*e24*e18-e30*e15*e27-e30*e25*e17+e30*e14*e28-e33*e21*e18+e10*e34*e28+e10*e24*e38-e10*e35*e27-e10*e25*e37-e20*e15*e37-e26*e32*e14+e26*e11*e35+e26*e31*e15-e36*e22*e14+e13*e32*e27+e16*e31*e25-e33*e11*e28; +A[9 + 10*15]=-e20*e35*e27-e20*e25*e37+e20*e34*e28+e20*e24*e38+e30*e24*e28-e30*e25*e27+e23*e32*e27+e23*e22*e37-e23*e31*e28-e23*e21*e38+e33*e22*e27-e26*e22*e34-e26*e32*e24+e26*e21*e35+e26*e31*e25-e36*e22*e24+e36*e21*e25-e33*e21*e28; +A[9 + 10*16]=-e33*e01*e38-e03*e31*e38+e00*e34*e38+e33*e32*e07+e03*e32*e37+e06*e31*e35-e00*e35*e37-e36*e32*e04-e06*e32*e34-e36*e02*e34+e36*e01*e35+e36*e31*e05+e30*e04*e38+e30*e34*e08-e33*e31*e08+e33*e02*e37-e30*e05*e37-e30*e35*e07; +A[9 + 10*17]=-e33*e31*e18-e33*e11*e38+e10*e34*e38+e30*e14*e38-e10*e35*e37-e30*e15*e37-e13*e31*e38+e13*e32*e37-e30*e35*e17+e33*e12*e37+e30*e34*e18+e33*e32*e17+e16*e31*e35-e16*e32*e34-e36*e12*e34-e36*e32*e14+e36*e11*e35+e36*e31*e15; +A[9 + 10*18]=-e20*e35*e37+e20*e34*e38+e30*e24*e38-e30*e35*e27-e30*e25*e37+e30*e34*e28+e23*e32*e37-e23*e31*e38-e33*e21*e38-e33*e31*e28+e33*e22*e37+e33*e32*e27+e26*e31*e35-e26*e32*e34-e36*e22*e34-e36*e32*e24+e36*e21*e35+e36*e31*e25; +A[9 + 10*19]=-e33*e31*e38-e30*e35*e37+e36*e31*e35+e33*e32*e37+e30*e34*e38-e36*e32*e34; + +} diff --git a/Utils_FeatureMatching/subfunctions/calibrated_fivepoint_helper.mexa64 b/Utils_FeatureMatching/subfunctions/calibrated_fivepoint_helper.mexa64 new file mode 100644 index 0000000..9ce9b88 Binary files /dev/null and b/Utils_FeatureMatching/subfunctions/calibrated_fivepoint_helper.mexa64 differ diff --git a/Utils_Metric/Eval_Metric.m b/Utils_Metric/Eval_Metric.m new file mode 100644 index 0000000..1a77c18 --- /dev/null +++ b/Utils_Metric/Eval_Metric.m @@ -0,0 +1,224 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Camera Exposure Control for Robust Robot Vision +% with Noise-Aware Image Assessment Metric +% +% Ukcheol Shin, Jinsun Park, Gyumin Shim, Francois Rameau, and In So Kweon +% +% IROS 2019 +% +% Please feel free to contact if you have any problems. +% +% E-mail : Ukcheol Shin (shinwc159@gmail.com / shinwc159@kaist.ac.kr) +% Robotics and Computer Vision Lab., EE, +% KAIST, Republic of Korea +% +% Project Page : https://sites.google.com/view/noise-aware-exposure-control +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Name : Eval_Metric +% +% Modified: +% +% 17 December 2019 +% +% Author: +% +% Ukcheol Shin +% +% Input : path_name - path of dataset +% output : None +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function [ ]= Eval_Metric(path_name) +close all; +clc; + +% Check number of inputs. +if nargin >2 + error('myfuns:somefun2:TooManyInputs', ... + 'requires at most 1 optional inputs'); +end + +% Flag for saving results +Save_flag = 1; + +% Read dataset list +output_folder =strcat(path_name(1:regexp(path_name,'DataSet_AE')-2),'\Results\Result_graph',path_name(regexp(path_name,'DataSet_AE')+10:length(path_name)-5)); + +mkdir(output_folder); +Files = dir(strcat(path_name,'\','*.jpg')); + +Results_Our = zeros(length(Files),3); +Results_Gradient = zeros(length(Files),3); +Results_Entropy = zeros(length(Files),3); +Results_Noise = zeros(length(Files),3); + +for k=1:length(Files) + fprintf('Path : %s, Processing %dth / %dth image .... \n',path_name,k,length(Files)); + + % Read files one-by-one + FileNames = Files(k).name; + FilePaths = strcat(path_name,'\',FileNames); + + % Parsing gain & Exposure time + index_iso = regexp(FileNames,'ISO-'); + index_exp = regexp(FileNames,'-ExpT-'); + index_jpg = regexp(FileNames,'.jpg'); + + ISO_ = FileNames(index_iso+4 : index_exp -1); + Exp_time_ = FileNames(index_exp+6 : index_jpg -1); + + % Evalutate images with a Image assessment metrics + [V_Ours, V_Gradient, V_Entropy, V_Noise] = Metric_Our(FilePaths); + + % Save each methods value + Results_Our(k,:) = [str2double(ISO_), str2double(Exp_time_), V_Ours ]; + Results_Entropy(k,:) = [str2double(ISO_), str2double(Exp_time_), V_Entropy ]; + Results_Gradient(k,:) = [str2double(ISO_), str2double(Exp_time_), V_Gradient ]; + Results_Noise(k,:) = [str2double(ISO_), str2double(Exp_time_), -V_Noise ]; +end + +% Write max value +if Save_flag == 1 + file_name = strcat(output_folder,'\','Selected_image_info.txt'); + fileID = fopen(file_name,'a'); + + % Save maximum point with Our metric + [~, idx] = max(Results_Our(:,3)); + MAX_value = Results_Our(idx,:); + str = strcat('Ours : ', ' ISO : ', num2str(MAX_value(1)),' E_T : ', num2str(MAX_value(2)), ' Value : ', num2str(MAX_value(3)), '\r\n'); + fprintf(fileID,str); + + % Save maximum point with Noise metric + [~, idx] = max(Results_Noise(:,3)); + MAX_value = Results_Noise(idx,:); + str = strcat('Noise : ', ' ISO : ', num2str(MAX_value(1)),' E_T : ', num2str(MAX_value(2)), ' Value : ', num2str(MAX_value(3)), '\r\n'); + fprintf(fileID,str); + + % Save maximum point with Entropy metric + [~, idx] = max(Results_Entropy(:,3)); + MAX_value = Results_Entropy(idx,:); + str = strcat('Entropy : ', ' ISO : ', num2str(MAX_value(1)),' E_T : ', num2str(MAX_value(2)), ' Value : ', num2str(MAX_value(3)), '\r\n'); + fprintf(fileID,str); + + % Save maximum point with Gradient metric + [~, idx] = max(Results_Gradient(:,3)); + MAX_value = Results_Gradient(idx,:); + str = strcat('Gradient : ', ' ISO : ', num2str(MAX_value(1)),' E_T : ', num2str(MAX_value(2)), ' Value : ', num2str(MAX_value(3)), '\r\n'); + fprintf(fileID,str); + + fclose(fileID); +end + +% plot values +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 1. Gradient-based Metric +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +x = unique(Results_Gradient(:,1)); +y = unique(Results_Gradient(:,2)); +[X,Y] = meshgrid(x,y); +Z = zeros(size(y,1),size(x,1)); + +for k = 1: size(Results_Gradient,1) + x_index = find( x == Results_Gradient(k,1)); + y_index = find( y == Results_Gradient(k,2)); + Z(y_index,x_index) = Results_Gradient(k,3); +end + +figure(1); +surfc(X,Y,Z); grid on; +xlabel('Gain(ISO)'); ylabel('Exposure Time(us)'); zlabel('Measure value'); title('Spatial Gradient Value Graph'); + +% save the result +if Save_flag == 1 + output = strcat(output_folder,'\','SpatialGradient'); +% saveas(gcf,output,'fig'); +% saveas(gcf,output,'pdf'); + saveas(gcf,output,'jpeg'); +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 2. Entropy-based Metric +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +x = unique(Results_Entropy(:,1)); +y = unique(Results_Entropy(:,2)); +[X,Y] = meshgrid(x,y); +Z = zeros(size(y,1),size(x,1)); + +for k = 1: size(Results_Entropy,1) + x_index = find( x == Results_Entropy(k,1)); + y_index = find( y == Results_Entropy(k,2)); + Z(y_index,x_index) = Results_Entropy(k,3); +end + +figure(2); +surfc(X,Y,Z); grid on; +xlabel('Gain(ISO)'); ylabel('Exposure Time(us)'); zlabel('Measure value'); title('Entropy Value Graph'); + +% save the result +if Save_flag == 1 + output = strcat(output_folder,'\','Entropy'); +% saveas(gcf,output,'fig'); +% saveas(gcf,output,'pdf'); + saveas(gcf,output,'jpeg'); +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 3. Noise-based Metric +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +x = unique(Results_Noise(:,1)); +y = unique(Results_Noise(:,2)); +[X,Y] = meshgrid(x,y); +Z = zeros(size(y,1),size(x,1)); + +for k = 1: size(Results_Noise,1) + x_index = find( x == Results_Noise(k,1)); + y_index = find( y == Results_Noise(k,2)); + Z(y_index,x_index) = Results_Noise(k,3); +end + +figure(3); +surfc(X,Y,Z); grid on; +xlabel('Gain(ISO)'); ylabel('Exposure Time(us)'); zlabel('Measure value'); title('Noise Value Graph'); + +% save the result +if Save_flag == 1 + output = strcat(output_folder,'\','Noise'); +% saveas(gcf,output,'fig'); +% saveas(gcf,output,'pdf'); + saveas(gcf,output,'jpeg'); +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 4. Ours: Grad + Noise + Entropy +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +x = unique(Results_Our(:,1)); +y = unique(Results_Our(:,2)); +[X,Y] = meshgrid(x,y); +Z = zeros(size(y,1),size(x,1)); +for k = 1: size(Results_Our,1) + x_index = find( x == Results_Our(k,1)); + y_index = find( y == Results_Our(k,2)); + Z(y_index,x_index) = Results_Our(k,3); + %fprintf('x: %d, y : %d, z: %d \n',list(k,1), list(k,2), list(k,3)) +end + +figure(4); +surfc(X,Y,Z); grid on; +xlabel('Gain(ISO)'); ylabel('Exposure Time(us)'); zlabel('Measure value'); title('Ours'); + +% save the result +if Save_flag == 1 + output = strcat(output_folder,'\','Ours'); +% saveas(gcf,output,'fig'); +% saveas(gcf,output,'pdf'); + saveas(gcf,output,'jpeg'); +end + +if Save_flag == 1 + output = strcat(output_folder,'\','workspace_result'); + save(output); +end +end + + diff --git a/Utils_Metric/Extract_Result.m b/Utils_Metric/Extract_Result.m new file mode 100644 index 0000000..4ae2943 --- /dev/null +++ b/Utils_Metric/Extract_Result.m @@ -0,0 +1,144 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Camera Exposure Control for Robust Robot Vision +% with Noise-Aware Image Assessment Metric +% +% Ukcheol Shin, Jinsun Park, Gyumin Shim, Francois Rameau, and In So Kweon +% +% IROS 2019 +% +% Please feel free to contact if you have any problems. +% +% E-mail : Ukcheol Shin (shinwc159@gmail.com / shinwc159@kaist.ac.kr) +% Robotics and Computer Vision Lab., EE, +% KAIST, Republic of Korea +% +% Project Page : https://sites.google.com/view/noise-aware-exposure-control +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Name : Extract_Result +% : Extract result image of each image assessment metric and upsampled workspace. +% +% Modified: +% +% 17 December 2019 +% +% Author: +% +% Ukcheol Shin +% +% Input : path_name - Path of each dataset +% output : None +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function Extract_Result(path_name) +close all; +clc; + +% Check number of inputs. +if nargin >2 + error('myfuns:somefun2:TooManyInputs', ... + 'requires at most 1 optional inputs'); +end + +% Load workspace matlab file +path_result = strcat(path_name(1:regexp(path_name,'DataSet_AE')-2),'\Results'); +workspace_file = strcat(path_result,'\Result_graph', path_name(regexp(path_name,'DataSet_AE')+10:length(path_name)-5), '\workspace_result.mat'); +load(workspace_file); + +Left_folder = path_name; +Right_folder = strcat(path_name(1:length(path_name)-5),'\right'); + +% Make output directory +Output_folder =strcat(path_result,'\Result_Exp', path_name(regexp(path_name,'DataSet_AE')+10:length(path_name)-5)); +Result_left_folder = strcat(Output_folder,'\left'); +Result_right_folder = strcat(Output_folder,'\right'); + +mkdir(Result_left_folder); +mkdir(Result_right_folder); + +% Copy each algorithms result img +for i = 1 : length(Files) + + % parse ISO/Exposure time + FileNames = Files(i).name; + index = regexp(FileNames,'ISO-'); + index2 = regexp(FileNames,'-ExpT-'); + index3 = regexp(FileNames,'.jpg'); + ISO_ = str2double(FileNames(index+4 : index2 -1)); + Exp_time_ = str2double(FileNames(index2+6 : index3 -1)); + + ImgLeftFile = strcat(Left_folder,'\',Files(i).name); + ImgRightFile = strcat(Right_folder,'\',Files(i).name); + + % If the maximum points of each method are matches, copy the image. + [~, idx] = max(Results_Our(:,3)); + MAX_value = Results_Our(idx,:); + if(ISO_ == MAX_value(1)) + if(Exp_time_ == MAX_value(2)) + saveLeftFile = strcat(Result_left_folder,'\Ours_ISO-',num2str(ISO_),'-ExpT-',num2str(Exp_time_),'.jpg'); + saveRightFile = strcat(Result_right_folder,'\Ours_ISO-',num2str(ISO_),'-ExpT-',num2str(Exp_time_),'.jpg'); + copyfile(ImgLeftFile, saveLeftFile); + copyfile(ImgRightFile, saveRightFile); + end + end + + % Add other alogorithms result + +end + +% Copy camera built-in AutoExposuer result img +path_AE = strcat(path_name(1:length(path_name)-5),'\AE'); +Files_AE = dir(strcat(path_AE,'\','*.jpg')); + +for i = 1 : length(Files_AE) + + % parse ISO/Exposure time + FileNames = Files_AE(i).name; + index = regexp(FileNames,'ExpT-'); + index2 = regexp(FileNames,'-ISO-'); + index3 = regexp(FileNames,'.jpg'); + Exp_time_ = str2double(FileNames(index+5 : index2 -1)); + ISO_ = str2double(FileNames(index2+5 : index3 -1)); + + if(strcmp(FileNames(1:6), 'Param1')) + ImgRightFile = strcat(path_AE,'\',Files_AE(i).name); + saveRightFile = strcat(Result_right_folder,'\AE_ISO-',num2str(ISO_),'-ExpT-',num2str(Exp_time_),'.jpg'); + copyfile(ImgRightFile, saveRightFile); + elseif(strcmp(FileNames(1:6), 'Param2')) + ImgLeftFile = strcat(path_AE,'\',Files_AE(i).name); + saveLeftFile = strcat(Result_left_folder,'\AE_ISO-',num2str(ISO_),'-ExpT-',num2str(Exp_time_),'.jpg'); + copyfile(ImgLeftFile, saveLeftFile); + end + +end + +% Copy workspace file & upsampled results +saveWorkSpaceFile = strcat(Output_folder,'\workspace_result.mat'); +copyfile(workspace_file, saveWorkSpaceFile); + +interval_dB = 0.1; +interval_ExpT = 10; +min_dB = min(x); +max_dB = max(x); +min_ExpT = min(y); +max_ExpT = max(y); + +[Xq, Yq] = meshgrid( min_dB : interval_dB : max_dB, min_ExpT : interval_ExpT : max_ExpT); +Zq= interp2(X,Y,Z,Xq,Yq,'cubic'); + +% Display interpolated surface +%surfc(Xq,Yq,Zq); grid on; hold on; +%set(gca,'FontName', 'Times New Roman','FontSize',17); +%xlabel('Gain','fontsize',20, 'fontweight','bold'); ylabel('ExpT','fontsize',20, 'fontweight','bold'); zlabel('Metric value','fontsize',20, 'fontweight','bold'); +%view(-40,45) + +if(max_dB == 20) dataset_flag = 0; % outdoor +elseif(max_dB == 24) dataset_flag = 1; %indoor + +saveWorkSpaceFile = strcat(Output_folder,'\','workspace_upsampled_result'); +save(saveWorkSpaceFile,'Xq','Yq','Zq','path_name', 'dataset_flag', 'Results_Our','interval_dB', 'interval_ExpT'); + +disp('Done.') +end + + + diff --git a/Utils_Metric/Metric_Our.m b/Utils_Metric/Metric_Our.m new file mode 100644 index 0000000..9d4c635 --- /dev/null +++ b/Utils_Metric/Metric_Our.m @@ -0,0 +1,183 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Camera Exposure Control for Robust Robot Vision +% with Noise-Aware Image Assessment Metric +% +% Ukcheol Shin, Jinsun Park, Gyumin Shim, Francois Rameau, and In So Kweon +% +% IROS 2019 +% +% Please feel free to contact if you have any problems. +% +% E-mail : Ukcheol Shin (shinwc159@gmail.com / shinwc159@kaist.ac.kr) +% Robotics and Computer Vision Lab., EE, +% KAIST, Republic of Korea +% +% Project Page : https://sites.google.com/view/noise-aware-exposure-control +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Name : Metric_Our +% Input : Img_path - Path of a image +% output : Value_Ours - Proposed image assessment value of the given image +% : Value_Grad - Gradient-based image assessment value of the given image +% : Value_Entorpy - Entropy-based image assessment value of the given image +% : Value_Noise - Noise-based image assessment value of the given image +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function [Value_Ours, Value_Grad, Value_Entropy, Value_Noise] = Metric_Our(Img_path) + +% Set hyper parameters +Resize_factor = 1.0; +Alpha = 0.4; +Beta = 0.4; + +% hyper parameter for gradient-based metric +Kg = 2; +Lambda = 10^3; +Gamma = 0.06; + +% hyper parameter for noise-based metric +Ke = 0.125; % 1/8 +p = 0.10; +T_lower = 15; +T_upper = 235; + +% Set flag for display +plot_flag = 0; + +%% 1. Noise-based Metric +Img = imread(Img_path); +Img = imresize(Img,Resize_factor); +Value_Noise = zeros(size(Img,3),1); + +for Channel = 1 : size(Img,3) + Image = uint8(Img(:,:,Channel)); + + [H,W] = size(Image); + + % 1. Estimate homogenous region mask based on adaptive edge thresholding + [Image_Grad, ] = imgradient(double(Image), 'Sobel').^2; + Grad_1D = reshape(Image_Grad, [1,H*W]); % 1D histogram + Sort_Grad_1D = sort(Grad_1D); + Gth = Sort_Grad_1D(1,int32(H*W*p)); % p% = 0.10 + HomogenousRegionMask = double(Image_Grad <= Gth); + + % 2. Estimate Unsaturated mask + UnsaturatedMask = zeros(H,W); + for i = 1 : H + for j = 1: W + if(T_lower <= Image(i,j) && Image(i,j) <= T_upper) + UnsaturatedMask(i,j) = 1; + else + UnsaturatedMask(i,j) = 0; + end + end + end + + % 3. Get integrated mask + UnSaturatedHomogenousMask = UnsaturatedMask .* HomogenousRegionMask; + + % 4. Estimate Noise level of the image + Ng = [ 1, -2, 1 ; + -2, 4, -2 ; + 1, -2, 1 ]; + + Laplacian_Image = conv2(double(Image),double(Ng)); + Laplacian_Image = Laplacian_Image(2:H+1,2:W+1); + Masked_Laplacian_Image = Laplacian_Image.*UnSaturatedHomogenousMask; + + % In the paper, I was missed the number of "6", plz refer the equation + % from "Immerkaer, John. "Fast noise variance estimation." Computer vision and image understanding 64.2 (1996): 300-302." + Ns = sum(sum(UnSaturatedHomogenousMask)); + Value_Noise(Channel) = sqrt(pi/2) * (1/(6*Ns)) * sum(sum(abs(Masked_Laplacian_Image))); + + % If there are no reliable regions, we follows the original noise + % estimation equation. + if(sum(sum(UnSaturatedHomogenousMask)) < H*W*0.0001) + Value_Noise(Channel) = sqrt(pi/2)*(1/(6*(W-2)*(H-2)))*sum(sum(abs(Laplacian_Image))); + end + + %% 7. Plot + if plot_flag == 1 + figure; + subplot(2,4,1); + imagesc(Image); + title('Input Img'); + + subplot(2,4,2); + imagesc(uint8(255*Image_Grad)); + title('Gradient Map'); + + subplot(2,4,3); + imagesc(uint8(255*HomogenousRegionMask)); + title('homogenous Mask Image'); + + subplot(2,4,4); + imshow(UnsaturatedMask); + title('Unsaturated Mask Image'); + + subplot(2,4,5); + imshow(UnSaturatedHomogenousMask); + title('UnSaturated Homogenous Mask Image'); + + subplot(2,4,6); + imagesc(uint8(Laplacian_Image)); + title('Laplacian image'); + + subplot(2,4,7); + imagesc(uint8(Masked_Laplacian_Image)); + title('Masked Laplacian image'); + end +end + +% the camera we used has a Bayer pattern, so we multiply 2 on the green channel, +% but empirically 'R+G+B/3' shows almost similar results. +if (size(Img_path,3) == 3) + Value_Noise = (Value_Noise(1) + 2*Value_Noise(2) + Value_Noise(3)) / 4; +else + Value_Noise = mean(Value_Noise); +end + + +%% 2. Gradient-based Metric +gray_Image = rgb2gray(Img); +[H,W] = size(gray_Image); + +% 1.normalize gradient image +[Image_Grad,] = imgradient(gray_Image); +G_norm = Image_Grad./sqrt(16 * 255 * 255 + 16 * 255 * 255); % normalize + +% In the paper "Auto-adjusting camera exposure for outdoor robotics using gradient information, IROS2014." +% The author used lambda = 10^3, Gamma = 0.06 in all experiments, so we follow the setup. +Ng = log(Lambda.*(1-Gamma)+1); +Mapped_Grad = zeros(H,W); +for i=1:H + for j=1:W + if G_norm(i,j)>=Gamma + Mapped_Grad(i,j)= log(Lambda * (G_norm(i,j) - Gamma) + 1)./ Ng; + else + Mapped_Grad(i,j) = 0; + end + end +end + +% Estimate grid-level statistics of gradient metric +num = 10; % num x num grid +Gridded_Grad = zeros(num,num); + +for i = 1:num + for j = 1:num + Gridded_Grad(i,j) = mean2(Mapped_Grad(1+H/num * (i-1) : H/num * (i-1) +H/num, 1+W/num * (j-1) :W/num * (j-1) + W/num)); + end +end +Gridded_Grad_1D = reshape(Gridded_Grad, [num*num,1]); +Grad_mean = mean(Gridded_Grad_1D); +Std_num = std(Gridded_Grad_1D); +Value_Grad = Grad_mean / Std_num; + +%% 3. Entropy-based Metric +Value_Entropy = Ke*entropy(gray_Image); + +%% 4. Proposed Metric +% Kg is scalling factor and empirically decided. +Value_Ours = Alpha*Kg*Value_Grad + (1-Alpha)*Value_Entropy - Beta*Value_Noise; +end \ No newline at end of file diff --git a/Utils_Metric/Test_HyperParam.m b/Utils_Metric/Test_HyperParam.m new file mode 100644 index 0000000..3407bd3 --- /dev/null +++ b/Utils_Metric/Test_HyperParam.m @@ -0,0 +1,105 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Camera Exposure Control for Robust Robot Vision +% with Noise-Aware Image Assessment Metric +% +% Ukcheol Shin, Jinsun Park, Gyumin Shim, Francois Rameau, and In So Kweon +% +% IROS 2019 +% +% Please feel free to contact if you have any problems. +% +% E-mail : Ukcheol Shin (shinwc159@gmail.com / shinwc159@kaist.ac.kr) +% Robotics and Computer Vision Lab., EE, +% KAIST, Republic of Korea +% +% Project Page : https://sites.google.com/view/noise-aware-exposure-control +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Name : Test_HyperParam +% : Test hyper parameter of proposed metric +% Input : path_name - Path of each dataset +% output : None +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function Test_HyperParam(path_name) +close all; +clc; + +% Check number of inputs. +if nargin >2 + error('myfuns:somefun2:TooManyInputs', ... + 'requires at most 1 optional inputs'); +end + +% load workspace matlab file +path_result = strcat(path_name(1:regexp(path_name,'DataSet_AE')-2),'\Results'); +workspace_file = strcat(path_result,'\Result_graph', path_name(regexp(path_name,'DataSet_AE')+10:length(path_name)-5), '\workspace_result.mat'); +load(workspace_file); + +Left_folder = path_name; +Right_folder = strcat(path_name(1:length(path_name)-5),'\right'); + +% make output directory +Output_folder =strcat(path_result,'\Result_HypeParam', path_name(regexp(path_name,'DataSet_AE')+10:length(path_name)-5)); +Result_left_folder = strcat(Output_folder,'\left'); +Result_right_folder = strcat(Output_folder,'\right'); + +mkdir(Output_folder); +mkdir(Result_left_folder); +mkdir(Result_right_folder); + +file_name = strcat(Output_folder,'\','max_value.txt'); +fileID = fopen(file_name,'a'); + +Test_Our = Results_Our; +Kg = 2; + +% Test hyper parameter +for Alpha = 0 : 0.2 : 1.0 + for Beta = 0 : 0.1 : 1 + fprintf('alpha : %d , beta : %d \n',Alpha,Beta); + Test_Our(:,3) = Alpha*Kg*Results_Gradient(:,3) + (1-Alpha)*Results_Entropy(:,3) - Beta*Results_Noise(:,3); + + % Write a result + [~, idx] = max(Test_Our(:,3)); + MAX_value = Test_Our(idx,:); + str = strcat('Alpha : ', num2str(Alpha), ' Beta : ', num2str(Beta) , ' ISO : ', num2str(MAX_value(1)),' E_T : ', num2str(MAX_value(2)), ' Value : ', num2str(MAX_value(3)), '\r\n'); + fprintf(fileID,str); + + % Copy left/right images according to the each maximum point + ImgLeftFile = strcat(Left_folder,'\',Files(idx).name); + ImgRightFile = strcat(Right_folder,'\',Files(idx).name); + + saveLeftFile = strcat(Result_left_folder,'\alpha_',num2str(Alpha*10),'_beta_',num2str(Beta*10), '_ISO-',num2str(MAX_value(1)),'-ExpT-',num2str(MAX_value(2)),'.jpg'); + saveRightFile = strcat(Result_right_folder,'\alpha_',num2str(Alpha*10),'_beta_',num2str(Beta*10), '_ISO-',num2str(MAX_value(1)),'-ExpT-',num2str(MAX_value(2)),'.jpg'); + copyfile(ImgLeftFile, saveLeftFile); + copyfile(ImgRightFile, saveRightFile); + + % plot values + figure(1); + x = unique(Test_Our(:,1)); + y = unique(Test_Our(:,2)); + [X,Y] = meshgrid(x,y); + Z = zeros(size(y,1),size(x,1)); + for k = 1: size(Test_Our,1) + x_index = find( x == Test_Our(k,1)); + y_index = find( y == Test_Our(k,2)); + Z(y_index,x_index) = Test_Our(k,3); + %fprintf('x: %d, y : %d, z: %d \n',list(k,1), list(k,2), list(k,3)) + end + + surfc(X,Y,Z); grid on; + xlabel('Gain(ISO)'); ylabel('Exposure Time(us)'); zlabel('Measure value'); + title('Ours'); + output = strcat(Output_folder,'\','Ours_Alpha_', num2str(Alpha*10), '_Beta_', num2str(Beta*10)); + %saveas(gcf,output,'fig'); + %saveas(gcf,output,'pdf'); + saveas(gcf,output,'jpeg'); + end +end + +fclose(fileID); +end + + +